此代码中嵌套承诺的目的是什么

What is the purpose of the nested promise in this code?

本文关键字:是什么 承诺 嵌套 代码      更新时间:2023-09-26

我正在尝试熟悉承诺及其工作原理。虽然这对我来说是一个新概念,但我相对确定我能理解其中的大部分。特别是我一直在看蓝鸟库,并通过示例进行研究。但是,页面上有一个代码片段我无法完全理解。

Promise.promisifyAll(needle);
var options = {};
var current = Promise.resolve();
Promise.map(URLs, function(URL) {
    current = current.then(function () {
        return needle.getAsync(URL, options);
    });
    return current;
}).map(function(responseAndBody){
    return JSON.parse(responseAndBody[1]);
}).then(function (results) {
    return processAndSaveAllInDB(results);
}).then(function(){
    console.log('All Needle requests saved');
}).catch(function (e) {
    console.log(e);
});

在此代码中,我了解needle库正在被承诺。我想我说current被设定为一个空洞的承诺是对的。

我的问题围绕着

current = current.then(function () {
    return needle.getAsync(URL, options);
});
return current;

法典。如果针头已经被承诺了,那么将其嵌套在另一个承诺中的目的是什么?

这是一种对异步调用进行排队并同时将它们交给 map 函数的可疑方式,以便生成所有结果数组的承诺。

那么它有什么作用呢?单独排队通常使用reduce,与current累加器的循环做同样的事情。它从空的承诺开始,并重复链接数组中每个 url 的回调;像下面的代码一样:

var current = Promise.resolve().then(function() {
    return needle.getAsync(URL[0], options);
}).then(function() {
    return needle.getAsync(URL[1], options);
}).then(function() {
    return needle.getAsync(URL[2], options);
}) …

但是,在map循环中使用时,它实际上会生成一个单个承诺数组,例如

var promises = [];
promises[0] = Promise.resolve().then(function() {
    return needle.getAsync(URL[0], options);
});
promises[1] = promises[0].then(function() {
    return needle.getAsync(URL[1], options);
});
promises[2] = promises[1].then(function() {
    return needle.getAsync(URL[2], options);
});
…

我要么使用reduce的方式,从Promise.resolve([])开始,逐步添加到该结果数组中,要么编写一个专用的scan(或mapAccum,无论您想如何命名它)函数并将其与Promise.all结合使用。

或者更好的是,只需使用Bluebird的内置{concurrency: 1}选项即可Promise.map

Bergi写了一个你应该阅读的好答案。以下是我如何使用.each编写该代码:

var get = Promise.promisify(needle.get);
Promise.each(URLs, get). // make the requests
       map(function(x){ return JSON.parse(x[1])} ). // parse response as json
       then(processAndSaveAllInDB).
       then(function(){ console.log("All Needle requests saved"); }).

请注意,您不需要catch因为 Bluebird 会发现未处理的拒绝并在这种情况下为您报告。

通常,当人们执行上面的代码时,他们关心顺序,尽管在原始代码中没有保证(地图改变了蓝鸟2中的行为,速度要快得多,但不能保证排队顺序)。