【问题标题】:How to make promises execute synchronously using generators如何使用生成器使 Promise 同步执行
【发布时间】:2017-10-30 02:46:41
【问题描述】:

我在这里关注博客文章: http://www.tivix.com/blog/making-promises-in-a-synchronous-manner

这表示生成器可用于同步 Promise 执行。

我知道这是一种不好的做法 - 我们正在使用类似 GWT 的框架(准确地说是 Urweb),它现在只理解同步 javascript 函数返回值。

以下代码取自那篇文章

{
  '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);
}

给出以下输出: 1 3 1000

但是如果承诺是同步的,那么输出应该是

1 1000 3

我做错了吗?还是不可能使用生成器使承诺同步?

【问题讨论】:

  • 文章有误。它允许您以顺序(“同步”)方式编写异步代码而不使用then,它不会使承诺同步(这是不可能的)。顺便说一句,在现代 Js 中使用 async/await 可以获得相同的优势语法。

标签: javascript ecmascript-6 es6-promise


【解决方案1】:

我做错了吗?

是的。所有应该显示同步的代码都必须进入生成器函数:

makeMeLookSync(function* () {
  let result = yield asyncTask();

  console.log(result);
  console.log(3);
});

或者是不可能使用生成器使承诺同步?

您可以永远使异步代码同步。生成器允许您编写看起来同步的代码,这意味着(并且在您链接到的文章中提到)代码是从上到下执行的:

尽可能简单地说:异步 JavaScript 不会在读取时执行 - 从上到下。

但这仅适用于我上面提到的生成器内部。 yield 关键字允许您以同步方式编写代码。注意函数的名字是makeMe<strong>Look</strong>Sync,而不是makeMeSync


话虽如此,ES2017 引入了async functions,它基本上在没有生成器和运行生成器的情况下做同样的事情:

{
  '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);
  }());
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-12
    • 1970-01-01
    • 2016-08-31
    • 2015-05-10
    • 2015-03-15
    • 2016-12-06
    • 2022-08-08
    • 2016-07-30
    相关资源
    最近更新 更多