I was just reading this fantastic article «Generators» and it clearly highlights this function, which is a helper function for handling generator functions:
function async(makeGenerator){ return function () { var generator = makeGenerator.apply(this, arguments); function handle(result){ // result => { done: [Boolean], value: [Object] } if (result.done) return Promise.resolve(result.value); return Promise.resolve(result.value).then(function (res){ return handle(generator.next(res)); }, function (err){ return handle(generator.throw(err)); }); } try { return handle(generator.next()); } catch (ex) { return Promise.reject(ex); } } }
which I hypothesize is more or less the way the async
keyword is implemented with async
/await
. So the question is, if that is the case, then what the heck is the difference between the await
keyword and the yield
keyword? Does await
always turn something into a promise, whereas yield
makes no such guarantee? That is my best guess!
You can also see how async
/await
is similar to yield
with generators in this article where he describes the 'spawn' function ES7 async functions.
functionality: yield and await can both be used to write asynchronous code that “waits”, which means code that looks as if it was synchronous, even though it really is asynchronous. await: This is an operator which used to wait for a Promise.
In a normal function, there is only one entry point: the invocation of the function itself. A generator allows you to pause the execution of a function and resume it later. Generators are useful when dealing with iterators and can simplify the asynchronous nature of Javascript.
They are two different things. One (fetch) is an API, that returns a promise. The other (async/await) is a part of the syntax of the JavaScript language and it provides you with one way (not the only way) to handle promises returned from functions or API calls such as fetch.
Among those features are generator functions and async/await. Generator functions give you the ability to pause and continue the execution of a program. In contrast, async/await gives you the ability to write asynchronous code without falling into "callback hell", which you risk when writing standard promises.
Well, it turns out that there is a very close relationship between async
/await
and generators. And I believe async
/await
will always be built on generators. If you look at the way Babel transpiles async
/await
:
Babel takes this:
this.it('is a test', async function () { const foo = await 3; const bar = await new Promise(resolve => resolve('7')); const baz = bar * foo; console.log(baz); });
and turns it into this
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; } this.it('is a test', _asyncToGenerator(function* () { // << now it's a generator const foo = yield 3; // <<< now it's yield, not await const bar = yield new Promise(resolve => resolve(7)); const baz = bar * foo; console.log(baz); }));
you do the math.
This makes it look like the async
keyword is just that wrapper function, but if that's the case then await
just gets turned into yield
, there will probably be a bit more to the picture later on when they become native.
You can see more of an explanation for this here: https://www.promisejs.org/generators/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With