Sunday, May 19, 2024
 Popular · Latest · Hot · Upcoming
1
rated 0 times [  2] [ 1]  / answers: 1 / hits: 62248  / 8 Years ago, thu, march 24, 2016, 12:00:00

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.


More From » node.js

 Answers
36

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/


[#62825] Monday, March 21, 2016, 8 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
ignacio

Total Points: 467
Total Questions: 128
Total Answers: 79

Location: Luxembourg
Member since Tue, Mar 14, 2023
1 Year ago
;