Typescript Async/Await Internals
Published: 2020-02-26 15:03:28

```javascript
"use strict";
 
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
```
This is the actual JavaScript implementation of the Typescript async/await construct. 

The _awaiter, simply returns a Promise which is created in compiled JavaScript like this:

```javascript
 function clickLinkByText(text) {
        return __awaiter(this, void 0, void 0, function () {
            var link;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, getFirstLinkByText(text)];
                    case 1:
                        link = _a.sent();
                        link.click();
                        return [2 /*return*/, link];
                }
            });
        });
    }
```
This code returns a promise which encapsulates a *generator function (a function which Yields something). In this case it Yields the array of (step, function). Why the Yields? Because JavaScript runtime is single threaded, the *generation function relinquishes control at Yield time, allowing the "main thread" to continue processing. In other words, each time a new "step" is called from the awaiter, the _generation Yields something regarding work flow.

The Typescript code was:

```typescript
  async function clickLinkByText(text) {
      let link = await getFirstLinkByText(text);
      link.click();
      return link;
   }
```

I like TypeScript and feel this shows us the power it can contain.  I'm pretty sure that this implementation was tested very well, and thus made it into the Typescript release.  Could you imagine rewritting the every time you wanted an async/await clone?  Some people would say just use Promises or Observables. Both would be correct because they all do the same thing.  I believe the async/await construct is easiest on the eyes, and immediately understood.

JWP2020