Javascript 蓝鸟扩散函数的错误

Javascript 蓝鸟扩散函数的错误,javascript,ecmascript-6,promise,Javascript,Ecmascript 6,Promise,当我开始写代码的时候 import Promise from 'bluebird'; const mongodb = Promise.promisifyAll(require('mongodb')); const MongoClient = mongodb.MongoClient; MongoClient.connect(url).then((db) => { return Promise.all([new WorkerService(db)]); }).spread((worke

当我开始写代码的时候

import Promise from 'bluebird';
const mongodb = Promise.promisifyAll(require('mongodb'));
const MongoClient = mongodb.MongoClient;
MongoClient.connect(url).then((db) => {
    return Promise.all([new WorkerService(db)]);
}).spread((workerService) => (
    Promise.all([new WorkerRouter(workerService)])
)).spread((workerRouter) => {
   app.use('/worker', workerRouter);
}).then(() => {
    httpServer.start(config.get('server.port'));
}).catch((err) => {
    console.log(err);
   httpServer.finish();
}))

我认为这是一个错误

}).spread(function (workerService) {
   ^

TypeError: MongoClient.connect(...).then(...).spread is not a function

请帮帮我。我做错了什么

我在这里看到了一些错误:

这里的根本原因是
MongoClient.connect(…)。然后(…)
没有返回蓝鸟承诺,因此没有
.spread()
方法。当您向Bluebird推荐一个接口时,它根本不会改变现有的方法。相反,它添加了带有“Async”后缀的新方法

所以,除非你告诉Mongo只做蓝鸟的承诺,那么

`MongoClient.connect(...).then(...)`
无论Mongo做出了什么样的承诺都会回来。您需要使用新的promisified方法:

MongoClient.connectAsync(...).then(...).spread(...)

我在代码中看到的其他一些问题:

1)
Promise.all()
希望您传递一系列承诺。但是当您这样做时:
Promise.all([new WorkerRouter(workerService)])
,您传递给它的是单个对象的数组,除非该对象本身是Promise,否则它就是错误的

2) 在此代码中:

}).spread((workerService) => (
    Promise.all([new WorkerRouter(workerService)])
))
您需要返回结果承诺,以便将其链接到链中:

}).spread((workerService) => (
    return Promise.all([new WorkerRouter(workerService)])
))
3) 但是,没有理由在单个元素数组上使用
Promise.all()
。如果这是一个承诺,那么就把它还给我

4) 看起来您也在尝试对同步代码的不同步骤使用承诺。除了让事情复杂化之外,没有理由这样做:

}).spread((workerService) => (
    Promise.all([new WorkerRouter(workerService)])    
)).spread((workerRouter) => {
   app.use('/worker', workerRouter);
}).then(() => {
    httpServer.start(config.get('server.port'));
})...
可以组合到以下各项:

)).spread((workerService) => {
    app.use('/worker', new WorkerRouter(workerService));
    httpServer.start(config.get('server.port'));
})...
而且,由于
新WorkerService(db)
可能也不会返回承诺,因此可能会进一步压缩

5) 然后,我们无法真正说明您为什么要首先尝试使用
.spread()
。只有当您有一个结果数组想要转换为多个命名参数时,它才有用,但您不需要有一个结果数组(因为没有理由对单个项使用
Promise.all()
,在现代版本的node.js中,确实没有理由使用
.spread()
因为您可以使用数组函数参数的ES6析构函数来完成与常规
.then()
相同的操作


我并不是说要完全按照你的每一行来做,但你可以做到这一点:

import Promise from 'bluebird';
const mongodb = Promise.promisifyAll(require('mongodb'));
const MongoClient = mongodb.MongoClient;
MongoClient.connectAsync(url).then((db) => {
    let service = new WorkerService(db);
    app.use('/worker', new WorkerRouter(service));
    // since httpServer.start() is async and there's no promise returning here,
    // this promise chain will not wait for the server to start
    httpServer.start(config.get('server.port'));
}).catch((err) => {
    console.log(err);
    httpServer.finish();
});

显然,`MongoClient.connect(…).then(…)`不是蓝鸟承诺。为什么要对单个参数使用
.spread()
?为什么要使用
promise.all()
并将长度为1的数组传递给它?这两个都是奇数。
新WorkerRouter(workerService)吗
返回一个承诺?它看起来不像是这样,所以我不知道你为什么要将它传递给
promise.all()
promise.all()
需要一系列承诺。我怀疑“承诺之外的新东西”将返回一个承诺因为,看起来你是新来的,让我解释一下关于堆栈溢出的一些情况。我们试图帮助你,但你似乎已经发布了,然后消失了。堆栈溢出并不是这样工作的。这个地方比典型的互联网论坛互动性强得多,你可能会在那里发布,然后第二天再来讨论看看你得到了什么答复。如果你在这里这样做,并且没有与问你问题的人互动,你的问题可能会因为没有回应或不清楚而被否决。