Javascript承诺单一函数回调

时间:2017-09-21 00:58:20

标签: javascript promise es6-promise

我有两种方法可以运行一系列初始化(需要按特定顺序进行)。

方法1:

dispatch('initialize1')
  .then(dispatch('initialize2'))
  .then(dispatch('initialize3'))
  .then(dispatch('initialize4'))
  .catch((error) => Log(error.message))

方法2:

dispatch('initialize1')
  .then(() => dispatch('initialize2'))
  .then(() => dispatch('initialize3'))
  .then(() => dispatch('initialize4'))
  .catch((error) => Log(error.message))

方法2工作得很好,但方法1似乎不等待每一个完成它才能进入下一个。

但这真让我感到困惑,因为我认为如果我用thens链接promises(没有回调函数),它会等待每个完成(同步);但是如果我把每个承诺放在一个回调中,那么一旦收到承诺,它就会转移到下一个承诺 - 但事实恰恰相反? 任何人都可以向我解释这个吗?

我不认为这是相关的,但发送来自Vue的Vuex商店。

3 个答案:

答案 0 :(得分:1)

在方法1中,您传递了调用函数dispatch 而不是将函数传递给Promise链的结果,这将导致首先调用dispatch函数在Promise链实际开始执行之前,即在初始化链时已经调用了dispatch函数。

您可以直接通过浏览器控制台运行以下代码来查看:

const dispatch = something => something

typeof dispatch('apple') === 'string' // true

typeof (() => { dispatch('apple') }) === 'function' // true

在方法2中,您这次正在传递函数,因此函数将被Promise称为在适当的时间而不是在开始时运行

答案 1 :(得分:0)

因为在第一种情况下你需要一个包装函数:

.then(function() {
  dispatch('initialize2')
})

在这里你做同样的事情:

.then(() => dispatch('initialize2'))

() => ...是与function() {...}类似的包装函数。

答案 2 :(得分:0)

你应该看看承诺应该如何运作。简而言之,它们由两部分组成,resolve算法和promise实例上可用的then方法。您的第一个示例无法工作,因为它不遵循then方法的语义(签名)。

它们如下:让p承诺,f一个JS值。致电p.then(f)我们会遇到以下情况:

  • 如果f不是function,则会被忽略,而p.then(f)会返回新的保证q,最终以与p相同的状态结算。< / LI>
  • 如果ffunction,那么当p与某个值结算时,调用p.then(f)将返回一个新的承诺q,该承诺将与f产生的值/误差。这是关键部分,也是使promises变得有趣的原因:传递给then attr的过程只会在原始承诺首次产生值/错误之后被称为,因此你的问题与例子1.

对承诺及其语义有一点点的承诺:then有两个参数,每个路径一个:值/错误。这些命名可能有所不同,但通常你会看到代码:

p.then(proceed, handle)

function proceed ( successfulValueFromSomewhere ) { // return new value or promise }


function handle ( anErrorFromSomewhere ) { // handle it by returning a value or a promise ( for retry cases ) }

我之前提到过resolve算法,这一部分对于理解如何从承诺的角度使用从这些处理程序返回的值来创建新的承诺至关重要。

此过程可确保您的第二个示例工作,它或多或少地起作用(请查看MDN上的规范或文档以进行深入审核)。其目的是转换对两种状态之一的承诺:fulfilled带有值或rejected带有错误。

v成为值,p unsettled承诺可以v解决。

  • 如果vthen方法,则使用函数function ( v2 ) { resolve(v2); }调用它:这意味着如果调用了回调,请使用提供的值重新运行该过程({{1} })。
  • 如果v2没有v方法,那么thenfulfill
  • 如果在解决过程中出现任何错误,那么v会出现错误。

这个过程并不是很困难,并解释了为什么promises可以很好地组合在一起:它们会在解析时调用彼此的reject方法,这意味着如果每个回调都返回一个promise,它们将按顺序执行。

对于承诺的规格还有一点点,我强烈建议任何人看看关于MDN的文章和this article关于这个新原语背后的动机以及它如何解决(某些)问题。

如果这个答案不明确,请发表评论我会更加清楚:)