【问题标题】:Bluebird Promises: Dynamically build props object, yet execute in parallelBluebird Promises:动态构建 props 对象,但并行执行
【发布时间】:2015-08-25 02:45:39
【问题描述】:

这里给出的例子:

https://github.com/petkaantonov/bluebird/blob/master/API.md#props---promise

Promise.props({
    pictures: getPictures(),
    comments: getComments(),
    tweets: getTweets()
}).then(function(result) {
    console.log(result.tweets, result.pictures, result.comments);
});

现在,如果我想动态构建 props 对象?喜欢

var propObj = {};

if (cond1) {
    propObj.tweets = getTweets();
}
if (cond2) {
    propObj.pictures = getPictures();
}
if (cond3) {
    propObj.comments = getComments();
}

Promise.props(propObj)
.then(function(result) {
    console.log(result);
});

以上代码无法按预期工作。 getTweets、getPictures、getComments 函数将在 propsObj 的构造过程中强制执行。

然而,我真正想要的是在Promises.props(propObj) 阶段并行执行这些函数,然后返回结果对象。有没有办法做到这一点?

【问题讨论】:

  • 在Promises.props(propObj) 之前执行它们有什么问题?它们都返回承诺,并将排队并在技术上并行运行。在Promises.props(propObj) 行中分配时,它们会在构建对象时按顺序执行(以返回承诺)。 Promises.props(propObj) 只是等待propObj 中的所有属性完成,然后再调用.then()。
  • 您的示例与 Bluebird 代码示例的工作方式相同。在 Bluebird 示例中,函数 getPictures() 和 getComments() 和 getTweets() 在实际调用 Promise.props() 之前被调用 - 与您的代码示例中相同。传递给Promise.props() 的是一个对象,其属性是承诺。已经调用了生成承诺的初始函数,并且操作已经在进行中。您的代码与 Bluebird 示例的工作方式没有什么不同。不确定您要解决什么问题。
  • 你当然会意识到,如果你的函数实际上只是同步函数调用,那么在常规 Javascript 中没有同步函数调用的并行操作,因为这里的主线程是单线程的。一次只执行一件事。如果操作是异步的(例如网络或异步文件 I/O),那么在调用启动后您会得到一些实际的并行操作,因为在初始调用返回后,本机代码库正在其他线程中处理事情),但这不会发生在常规同步函数调用中。
  • 你可以通过写Promise.props({/* object literal */}).then(...);来避免propObj的赋值。
  • @Steven10172 谢谢。这澄清了我的理解

标签: javascript promise bluebird


【解决方案1】:

把我的 cmets 变成一个答案,或许可以结束这个问题......

您的示例与 Bluebird 代码示例的工作方式相同。在 Bluebird 示例中,函数 getPictures() 和 getComments() 和 getTweets() 在实际调用 Promise.props() 之前被调用 - 与您的代码示例中相同。传递给Promise.props() 的是一个对象,其属性是承诺。

那么,在您的示例和 Bluebird 示例中发生的情况如下:

  1. if (cond1),启动 getTweets() 并将生成的承诺分配给 propObj.tweets。该异步操作在后台继续进行。
  2. if (cond2),启动 getPictures() 并将生成的承诺分配给 propObj.pictures。该异步操作在后台继续进行。
  3. if (cond3),启动 getComments() 并将生成的承诺分配给 propObj.cmets。该异步操作在后台继续进行。
  4. 调用promise.props(propObj),它只是迭代propObj 的属性,然后等待调用.then() 处理程序,直到它找到的所有承诺都完成。
  5. 最终所有异步操作都完成并调用.then() 处理程序。

已经调用了生成承诺的初始函数,并且操作已经在进行中。您的代码与 Bluebird 示例的工作方式没有什么不同。不确定您要解决什么问题。

你当然会意识到,如果你的函数实际上只是同步函数调用,那么在常规 Javascript 中就没有同步函数调用的并行操作,因为这里的主线程是单线程的。一次只执行一件事。如果操作是异步的(例如网络或异步文件 I/O),那么在调用启动后您会得到一些实际的并行操作,因为在初始调用返回后,本机代码库正在其他线程中处理事情),但这不会发生在常规同步函数调用中。

【讨论】:

  • 这样做的问题是他们永远不会执行并返回一个承诺
  • @Steven10172 - 答案重写。
猜你喜欢
  • 1970-01-01
  • 2015-10-08
  • 2015-04-17
  • 1970-01-01
  • 2015-06-15
  • 2016-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多