【问题标题】:Can I force the resolution of a promise to await results in javascript?我可以强制解决承诺以等待 javascript 中的结果吗?
【发布时间】:2015-07-09 16:40:23
【问题描述】:

这个问题有点学术,因为我没有真正的需要来做这个。

我想知道是否可以强制将承诺解析为函数的返回值,这样函数调用者不知道函数包含承诺的异步操作。

在 .NET 中,我可以通过使用 Task[]return Task.Result 上的函数来执行此类操作,这会导致调用者等待任务的完成,而调用者不会知道或关心工作是否已使用任务完成.

【问题讨论】:

  • 一个代码示例会很好。
  • 在什么情况下?节点还是浏览器?
  • 你的意思是像这样的伪代码吗? var foo = promise.resolve();
  • @Tivie 在浏览器中,是的,就像var foo = promise.resolve() 这样,如果承诺解决了一个数字 foo 是一个数字......目的是让调用者混淆异步工作正在发生。
  • 我倾向于说这是不可能的。使某些东西异步的唯一方法......同步,是等待解决。在浏览器中,据我所知,您无法阻止脚本执行,所以...

标签: javascript asynchronous promise bluebird


【解决方案1】:

如果您使用的是 ES6,您可以使用生成器来制作这样的代码。它本质上接近于对 promise 的“阻塞”,所以你有一个长时间运行的方法,它只返回你想要的值,但 async/promises 隐藏在幕后。

let asyncTask = () =>
  new Promise(resolve => {
    let delay = Math.floor(Math.random() * 100);

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

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

  console.log(result);
});

更多解释和来源在这里:http://www.tivix.com/blog/making-promises-in-a-synchronous-manner/

Here is the code 在 Babeljs.io 上编译

【讨论】:

  • (加一个)这样的东西会在浏览器上下文中工作吗?
  • 这将在支持生成器的浏览器中工作,是的。否则你可以用 Babel 将它编译成 ES5,它几乎可以在任何地方工作。
  • Promise 在此示例中是一个通用函数,因此您需要提供它。生成器有一个由 Babel(ES6 转译器)babeljs.io/docs/learn-es2015/#generators 提供的 polyfill。目前这一切都有点前沿,但没有什么不能在浏览器中运行。
  • 这不起作用“函数调用者不知道”。请在您的回答中更清楚地说明这一点。
  • @Jan:关键是这不会发生在幕后。调用者需要知道它正在调用生成器,并将包装器放在正确的位置。唯一的优点是控制结构可以以同步方式编写。
猜你喜欢
  • 2020-07-13
  • 2019-06-30
  • 1970-01-01
  • 1970-01-01
  • 2018-03-19
  • 2019-04-29
  • 2021-03-07
  • 2018-04-17
  • 2018-04-02
相关资源
最近更新 更多