【问题标题】:Promise not calling "then" callback承诺不调用“then”回调
【发布时间】:2016-06-10 18:13:54
【问题描述】:

C#/Dart 的 async/await 功能有点宠坏了我。我注意到 ES7 提出了类似语法的提议,并且 there is a library 将该功能添加到 Node.JS 应用程序中。

这个库在浏览器中不起作用。我想通过尝试编写自己的迷你解决方案可能会帮助我了解原因,所以我决定尝试一下,只是为了教育自己。 This is my attempt so far,在 Github Gist 上。我在下面包含了 sn-ps。

await 函数中:

function await (promise) {

  /* PromiseState declared here */

  var self = {
    result: null,
    state: PromiseState.pending
  };

  function onPromiseUpdate(context, newState) {
    return function (value) {
      console.log("Promise Updated!");
      context.result = value;
      context.state = newState;
    }
  }

  console.log("awaiting");
  // this never shows the Promise to be pending (using example below)
  console.log(promise);
  promise
    .then(onPromiseUpdate(self, PromiseState.resolved)) // this is never called
    .catch(onPromiseUpdate(self, PromiseState.rejected));

  // Shouldn't this not block the app if it's inside a Promise?
  while (self.state == PromiseState.pending) ;
  console.log("delegating");

  /* just returning the value here */
}

例子:

// is there another way to pass 'await' without a parameter?
unstableFunc = async(function (await) { 
  console.log("running unstable");
  if(Math.random() > 0.5) return Math.random() * 15 + 5;
  else throw "fail";
});

expensiveFunc = async(function (await, x, y) {
  result = await(unstableFunc())
  for (var i = y * 8; i >= 0; i--) {
    result *= i ** y / x;
    console.log(result);
  }
  return result;
});


window.addEventListener('load', function () {
  console.log("about to do something expensive");
  // 'expensiveFunc' returns a Promise. Why does this block the webpage?
  expensiveFunc(10, 2).then(function (val) {
    console.log("Result: " + val.toString());
  });
  console.log("called expensive function");
});

运行时,浏览器没有完成加载。这与我设置的循环有关,以检查 Promise 的状态正在解决,但这不是我问题的重点。我想知道为什么没有调用thencatch 回调。记录时,控制台从不记录未决的 Promise,我一直认为 thencatch 会在未来未未决的情况下立即执行它们的回调。为什么在这种情况下不是这样?

【问题讨论】:

  • 哇,你为什么要使用无限循环来检查承诺是否已经实现?
  • @HenriqueBarcelos 我为自己感到羞耻,因为您可能很害怕。在我正在尝试做的事情的范围内,有没有更好的方法来检查?
  • 不定式循环将阻塞事件循环,防止任何事件或回调无限期触发。使用断点或 console.log。
  • @WillemD'Haeseleer 呵呵。 Promise 中的所有内容不是异步执行的吗?我认为 promise 中的所有内容都不会阻塞主线程
  • 不,promise 与使同步事物异步无关。如果它阻塞了事件循环,它就会阻塞它,不管它在哪里当它运行时

标签: javascript node.js asynchronous promise async-await


【解决方案1】:

到达/执行这行代码的那一刻:

while (self.state == PromiseState.pending) ;

您的脚本将被永久阻止(或直到​​选项卡崩溃或浏览器将其终止)。当该循环正在运行时,回调不能运行(也不能运行其他任何东西),因此您的承诺状态永远不会更改为挂起,从而导致无限循环。涉及承诺不会改变上述任何内容。

【讨论】:

    猜你喜欢
    • 2013-06-15
    • 1970-01-01
    • 1970-01-01
    • 2017-12-05
    • 1970-01-01
    • 2016-06-15
    • 1970-01-01
    • 1970-01-01
    • 2016-06-02
    相关资源
    最近更新 更多