Reputation: 13734
I am following the blog article here : http://www.tivix.com/blog/making-promises-in-a-synchronous-manner
which says that generators could be used to synchronize promise execution.
I know it's a bad practice - we're using a GWT like framework (Urweb to be precise) which as of now understands only synchronous javascript function return values.
Following code taken from that article
{
'use strict';
let asyncTask = () =>
new Promise(resolve => {
let delay = 1000;
setTimeout(function () {
resolve(delay);
}, delay);
});
let makeMeLookSync = fn => {
let iterator = fn();
let loop = result => {
!result.done && result.value.then(res =>
loop(iterator.next(res)));
};
loop(iterator.next());
};
console.log(1);
makeMeLookSync(function* () {
let result = yield asyncTask();
console.log(result);
});
console.log(3);
}
gives the following output :
1
3
1000
But if the promise was made synchronous, the output should have been
1
1000
3
Am I doing it wrong ? Or is it not possible to make the promise synchronous using generators ?
Upvotes: 0
Views: 4080
Reputation: 817208
Am I doing it wrong ?
Yes. All the code that should appear to be synchronous would have to go inside the generator function:
makeMeLookSync(function* () {
let result = yield asyncTask();
console.log(result);
console.log(3);
});
Or is it not possible to make the promise synchronous using generators ?
You can never make asynchronous code synchronous. Generators allow you to write code that looks synchronous, which means (and which is mentioned in the article you linked to) that the code is executed from top to bottom:
To put it as simply as possible: async JavaScript does not execute as it reads - top to bottom.
But that only works inside the generator as I mentioned above. The yield
keyword is what allows you to write the code in a synchronous fashion. Note that the name of the function is makeMeLookSync
, not makeMeSync
.
Having said that, ES2017 introduced async
functions which basically do the same thing without generators and a runner to execute the generators:
{
'use strict';
let asyncTask = () =>
new Promise(resolve => {
let delay = 1000;
setTimeout(function() {
resolve(delay);
}, delay);
});
console.log(1);
(async function() {
let result = await asyncTask();
console.log(result);
console.log(3);
}());
}
Upvotes: 3