【问题标题】:how does promise work in javascript承诺如何在 JavaScript 中工作
【发布时间】:2014-08-19 17:50:12
【问题描述】:

所以我使用的是最新版本的 angular,

我写过这样的代码

$q.all({
  a: $q.then(func1, failHandler),
  b: $q.then(func2, failHandler),
  c: $q.then(func3, failHandler),
}).then(func4);

执行是否总是保证为func1、func2、func3、func4?

因为我在其他三个之前触发了 func4。这就引出了另一个问题。

$q.then(callbacks).then 是否总是在触发下一个 then 之前触发回调?

【问题讨论】:

  • 您实际上想要完成什么? .all() 不适用于顺序操作 - 它适用于并行操作。
  • 请给我们看funk1funk2func3的源代码。这段代码也充满了不正确的语法——即$q 没有公开.then 方法(你的意思是.when
  • ... $q.all({}) 吐出一个承诺,不是吗?

标签: javascript angularjs queue promise q


【解决方案1】:

免责声明:

以下示例均不建议在实际应用程序中使用,也不是最佳实践或任何东西。实际上,其中一些是The Deferred anti-pattern。我只是想演示它是如何工作的。

为了回答你的问题,我们先做一些实验。

给定这样的回调:

function okHandler(value) {
  console.log(value + ' has been called.');
  return value;
}

function doneHandler(values) {
  console.log('Done! : ' + JSON.stringify(values));
}

function delayed(value, delay) {
  var deferred = $q.defer();

  $timeout(function () {
    deferred.resolve(value);
  }, delay);

  return deferred.promise;
}

平行:

$q.all({
  a: $q.when('a').then(okHandler),
  b: $q.when('b').then(okHandler),
  c: $q.when('c').then(okHandler),
}).then(doneHandler);

结果:

a has been called.
b has been called.
c has been called.
Done! : {"a":"a","b":"b","c":"c"} 

与延迟模拟并行:

$q.all({
  a: delayed('da', 200).then(okHandler),
  b: delayed('db', 100).then(okHandler),
  c: delayed('dc', 300).then(okHandler),
}).then(doneHandler);

结果:

db has been called.
da has been called.
dc has been called.
Done! : {"b":"db","a":"da","c":"dc"} 

顺序:

delayed('sa', 400).then(okHandler).then(function () {
  delayed('sb', 100).then(okHandler).then(function () {
    delayed('sc', 10).then(okHandler).then(doneHandler);
  })
});

结果:

sa has been called.
sb has been called.
sc has been called.
Done! : "sc" 

顺序替代样式:

delayed('ssa', 600)
  .then(okHandler)
  .then(delayed.bind(null, 'ssb', 100))
  .then(okHandler)
  .then(delayed.bind(null, 'ssc', 10))
  .then(okHandler)
  .then(doneHandler);

结果:

ssa has been called.
ssb has been called.
ssc has been called.
Done! : "ssc"

Plunker 示例: http://plnkr.co/edit/dNZ8koAS4G6fNmahfmj6?p=preview

现在让我们看看你的问题。

问:执行是否总是保证为func1func2func3func4

A:不,只有func4 保证最后执行。 func1func2func3 可以按任意顺序执行。

问:$q.then(callbacks).then 是否总是在触发下一个 then 之前触发回调?

答:是的!

【讨论】:

  • -1 虽然看起来您在这个答案上付出了很多努力(这很好,谢谢),但它包含一些难以忽视的不准确之处。即第一个示例中的延迟反模式和以下示例中没有显示任何内容(那里的执行顺序没有真正保证)。由于某种原因,“顺序”版本具有(不必要的)嵌套等。修复这些问题,我很乐意删除我的反对票。
  • @BenjaminGruenbaum 感谢您的评论。但是我并没有说应该使用上述任何示例,也不是最佳实践或任何东西。我实际上已经从你那里了解到The Deferred anti-pattern。我只是想演示这些示例是如何工作的(对不起,如果我做得不好)并回答 OP 的具体问题。
  • 通过将它们包含在 Stack Overflow 上的答案中而不是发出警告 - 它们被使用,人们认为它们是最佳实践 :)如果你能解决这些问题,那就太棒了。
  • @BenjaminGruenbaum 今天没时间了。我在顶部添加了免责声明,明天将尝试解决这些问题。再次感谢。
【解决方案2】:

您需要区分 promisesQ

Promises 是一个具有then 属性的高级构造。

试试$q.defer(),别忘了解决它。

【讨论】:

  • 我想我理解承诺,但我不知道你刚刚写了什么。请考虑改写它。
猜你喜欢
  • 2019-08-29
  • 1970-01-01
  • 1970-01-01
  • 2014-12-16
  • 2018-05-27
  • 1970-01-01
  • 1970-01-01
  • 2019-02-05
  • 2014-11-07
相关资源
最近更新 更多