Promise.all(...).spread 不是并行运行 Promise 时的函数

Posted

技术标签:

【中文标题】Promise.all(...).spread 不是并行运行 Promise 时的函数【英文标题】:Promise.all(...).spread is not a function when running promises in parallel 【发布时间】:2017-08-02 16:18:23 【问题描述】:

我正在尝试使用 sequelize 并行运行 2 个 Promise,然后在 .ejs 模板中呈现结果,但我收到此错误:

 Promise.all(...).spread is not a function

这是我的代码:

var environment_hash = req.session.passport.user.environment_hash;
var Template  = require('../models/index').Template;
var List      = require('../models/index').List;

var values =  
    where:  environment_hash: environment_hash,
             is_deleted: 0 
                            
;

template = Template.findAll(values);
list = List.findAll(values);


Promise.all([template,list]).spread(function(templates,lists) 

    res.render('campaign/create.ejs', 
        templates: templates,
        lists: lists
    );

);

我该如何解决这个问题?

【问题讨论】:

.spread() 不是标准的承诺方法。它在 Bluebird Promise 库中可用 - 你在使用它吗?您包含的代码没有显示这一点。您也可以只使用.then(results => ...) 并以results[0]results[1] 访问结果。 谢谢,我不知道。我导入了 BlueBird,它现在可以工作了。 "I'm trying to run 2 promises in parallel". 不,你不是因为你不能,因为 JS 是单线程的。你正在处理的是你不知道哪个承诺会先结束。 @ankitbug94,不过还是可以并行IO操作。 根据我之前的评论,我发布了一个答案,为您提供了三种不同的解决方案。其中最优雅的是使用破坏来完全消除对 .spread() 的需要,尽管出于以下原因我仍然推荐 Bluebird:Are there still reasons to use promise libraries like Q or BlueBird now that we have ES6 promises? 【参考方案1】:

因为它解决了你的问题,所以我会把我的评论变成答案。

.spread() 不是标准的 promise 方法。它在 Bluebird Promise 库中可用。您包含的代码没有显示这一点。三种可能的解决方案:

直接访问数组值

您可以只使用.then(results => ...) 并以results[0]results[1] 访问结果。

包括 Bluebird Promise 库

您可以包含 Bluebird 承诺库,以便您可以访问 .spread()

var Promise = require('bluebird');

在回调参数中使用解构

在最新版本的 nodejs 中,您还可以使用解构赋值,这样就不需要 .spread(),如下所示:

Promise.all([template,list]).then(function([templates,lists]) 
    res.render('campaign/create.ejs', templates, lists);
);

【讨论】:

+1 destructuring assignment ,或者更好地称之为“解构参数”【参考方案2】:

您可以在没有非标准Bluebird 功能的情况下编写它,并保持更少的依赖关系。

Promise.all([template,list])
  .then(function([templates,lists]) 
  ;

ES6 Destructuring assignment

Promise.all([
  Promise.resolve(1),
  Promise.resolve(2),
]).then(([one, two]) => console.log(one, two));

【讨论】:

【参考方案3】:

这是Bluebird Promise 功能,您可以通过Sequelize.Promise 访问它,而无需安装Bluebird 模块本身

Sequelize.Promise.all(promises).spread(...)

【讨论】:

【参考方案4】:

我需要安装 BlueBird。

npm install bluebird

然后:

var Promise = require("bluebird");

【讨论】:

最好不要使用这些特定的 API。 ES6 有这么多的传播特性..

以上是关于Promise.all(...).spread 不是并行运行 Promise 时的函数的主要内容,如果未能解决你的问题,请参考以下文章

Promise.all() 不等待异步进程

promise.all 不返回实际结果

实现promise.all方法

Promise.all()使用方法

Promise.All不等待Promise解决

在嵌套 forEach 中的 Promise.all 之前评估 Promise,导致 Promise.all 为空