有不止一种方法可以做到这一点:
嵌套回调
如果没有 promise,你可以嵌套回调:
router.post('/search', (req, res) => {
var collection = db.get().collection('styles')
var data = [];
collection.distinct('make.name', (err, docs) => {
if (err) {
// ALWAYS HANDLE ERRORS!
}
data.push({'make': docs });
collection.distinct('model', (function (err, docs) {
if (err) {
// ALWAYS HANDLE ERRORS!
}
data.push({'model': docs });
res.send(data);
}))
});
});
这将是最简单的方法,但请注意,如果这两个请求可以并行完成,则效率不高。
async 模块
您可以使用async 模块:
router.post('/search', (req, res) => {
var collection = db.get().collection('styles')
var data = [];
async.parallel({
make: cb => collection.distinct('make.name', cb),
model: cb => collection.distinct('model', cb),
}, (err, responses) => {
if (err) {
// ALWAYS HANDLE ERRORS!
}
data.push({'make': responses.make });
data.push({'model': responses.model });
res.send(data);
});
});
见:https://caolan.github.io/async/docs.html#parallel
但这可能仍然不是最方便的方法。
ES2017 async/await
如果您要拨打 30 个电话,最灵活的方法是:
- 使用返回承诺的函数而不是接受回调的函数
- 如果可以或至少使用基于生成器的协程,请使用 async/await
- 当逻辑需要按顺序运行时等待承诺(或产生承诺)
- 将
Promise.all() 用于可以并行完成的任何事情
使用 async/await,您的代码可能如下所示:
// in sequence:
var make = await collection.distinct('make.name');
var model = await collection.distinct('model');
// use 'make' and 'model'
或者:
// in parallel:
var array = await Promise.all([
collection.distinct('make.name'),
collection.distinct('model'),
]);
// use array[0] and array[1]
async/await 的一大优势是错误处理:
try {
var x = await asyncFunc1();
var array = await Promise.all([asyncFunc2(x), asyncFunc3(x)]);
var y = asyncFunc4(array);
console.log(await asyncFunc5(y));
} catch (err) {
// handle any error here
}
您只能在使用async 关键字创建的函数内部使用它。有关详细信息,请参阅:
有关浏览器的支持,请参阅:
有关 Node 中的支持,请参阅:
在你没有原生支持 async 和 await 的地方你可以使用 Babel:
或者在语法稍有不同的情况下使用基于生成器的方法,例如 co 或 Bluebird 协程:
查看这些答案了解更多信息: