将 BlueBird Promise 同步链接到一个数组中

Posted

技术标签:

【中文标题】将 BlueBird Promise 同步链接到一个数组中【英文标题】:Synchronously chain BlueBird promises together within an array 【发布时间】:2016-05-24 20:05:04 【问题描述】:

我正在尝试同步执行一系列承诺,将它们链接在一起,但仅根据条件添加某些承诺..

这是我的意思的一个例子:

const Promise = require('bluebird')

const funcA = int => new Promise( res => res(++int) )
const funcB = int => new Promise( res => res(++int) )
const funcC = int => new Promise( res => res(++int) )

let mainPromise = funcA(1)

// Only execute the funcB promise if a condition is true
if( true )
    mainPromise = mainPromise.then(funcB)

mainPromise = mainPromise.then(funcC)

mainPromise
    .then( result =>  console.log('RESULT:',result))
    .catch( err => console.log('ERROR:',err))

如果布尔值为真,则输出为:RESULT: 4,如果为假,则为RESULT: 3,这正是我想要完成的。

我认为应该有更好、更清洁的方法来做到这一点。我正在使用 Bluebird Promise 库,它非常强大。我尝试使用Promise.join,但没有产生预期的结果,Promise.reduce 也没有(但我可能做错了)

谢谢

【问题讨论】:

你能告诉我们你是如何使用Promise.reduce的吗? 只是吹毛求疵,但promises are not executed 您想评估funcA() 已解决时的条件,还是在构建链时静态已知(如您的示例中)?还是没关系? 【参考方案1】:

您正在链接异步函数。将承诺更多地视为返回值,而不是那么令人兴奋。

你可以像这样把函数放在一个数组中,然后过滤数组:

[funcA, funcB, funcC]
  .filter(somefilter)
  .reduce((p, func) => p.then(int => func(int)), Promise.resolve(1))
  .catch(e => console.error(e));

或者,如果您只是在寻找一种更好的方式来编写序列中的条件,您可以这样做:

funcA(1)
  .then(int => condition ? funcB(int) : int)
  .then(funcC);
  .catch(e => console.error(e));

如果你使用的是 ES7,你可以使用异步函数:

async function foo() 
  var int = await funcA(1);
  if (condition) 
    int = await funcB(int);
  
  return await funcC(int);

【讨论】:

或者,他可能想做.then(condition ? funcB : (int => int)) 对,我知道它们是异步的,我的意思是我希望 Promise 以特定的顺序执行,将解析的数据从一个传递到另一个。 - 对于您的第一个示例,只需将func* 推送到数组而不使用过滤器就可以了?有没有办法为第一个定义参数? 我刚刚发现this thread似乎有一个很好的答案...(我只是在相关链接下找到) 对。我已经编辑了答案以将1 作为初始值传递给reduce【参考方案2】:

我找到了一个很好的相关线程here。使用相同的逻辑,我能够做到这一点:

const Promise = require('bluebird')

const funcA = int => new Promise( res => res(++int) )
const funcB = int => new Promise( res => res(++int) )
const funcC = int => new Promise( res => res(++int) )

const toExecute = [funcA, funcB]

if( !!condition )
    toExecute.push( funcC )

Promise.reduce( toExecute, ( result, currentFunction ) => currentFunction(result), 1)
    .then( transformedData => console.log('Result:', transformedData) )
    .catch( err => console.error('ERROR:', err) )

与我原来的帖子中发布的结果相同

【讨论】:

以上是关于将 BlueBird Promise 同步链接到一个数组中的主要内容,如果未能解决你的问题,请参考以下文章

Bluebird Promise Chains: 'Catch' with Result

为啥在使用promise时使用Q,bluebird框架? [复制]

非 Promise 值的“等待”无效(Bluebird 承诺)

Bluebird Promise.all - 多个 Promise 完成聚合成功和拒绝

使用 bluebird 和 coffeescript 的简单 promise 示例在一半时间内有效

Promise.resolve 与新的 Promise(resolve)