简体   繁体   中英

How to make promises execute synchronously using generators

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 ?

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 makeMe Look Sync , 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); }()); } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM