node.js承诺:嵌套在then()链中的promise的then()不会被解析

时间:2016-01-10 23:28:34

标签: javascript node.js promise

编写一个演示脚本来理解promises我在一个then()中嵌套了多个promise(使用promises.all()在所有promises解析后继续)。嵌套的promise的then()s无法解析:

var Promise = require("bluebird");

var array = [];

// push promises onto array
new Promise(function(resolve, reject) {
    setTimeout(function() { 
        for (var i = 5 - 1; i >= 0; i--) {
            array.push(returnapromise());
            console.log("pushed promise number", i, "onto array");
        }
        resolve();
    }, 300);
})

.then(function() {
    new Promise.all(array).then(function() {
        console.log("\nall done\n");
    });
});

// function that returns a promise
var returnapromise = function() {
    return new Promise(function(yolo) {

        new Promise(function() {
            setTimeout(function() { 
                console.log("async function within nested promise");
            }, 200);
        })

        .then(function() {
            setTimeout(function() { 
                console.log("async function within then one")
            }, 100);
        })

        .then(function() {
            setTimeout(function() { 
                console.log("async function within then two")
                yolo();
            }, 50);
        });

    }) // eof returned promise

}; // eof returnapromise()

但是,使用嵌套promise中的回调可以实现所需的目标,如下所示:

var Promise = require("bluebird");

var array = [];

// push promises onto array
new Promise(function(resolve, reject) {
    setTimeout(function() { 
        for (var i = 5 - 1; i >= 0; i--) {
            array.push(returnapromise());
            console.log("pushed promise number", i, "onto array");
        }
        resolve();
    }, 300);
})

.then(function() {
    new Promise.all(array).then(function() {
        console.log("\nall done\n");
    });
});

// function that returns a promise
var returnapromise = function() {
    return new Promise(function(yolo) {

        new Promise(function() {
            setTimeout(function() { 
                console.log("async function within nested promise");
                one()
            }, 200);

            var one = function() {
                setTimeout(function() { 
                    console.log("cb one")
                    two();
                }, 100);
            };

            var two = function() {
                setTimeout(function() { 
                    console.log("cb two")
                    yolo();
                }, 50);
            };

        }) // eof nested promise

    }) // eof returned promise

}; // eof returnapromise()

我如何编写嵌套的promises,然后()s实际得到解决?

1 个答案:

答案 0 :(得分:6)

returnapromise()的第一个版本中,您创建了两个promises,一个嵌套在另一个中。

内部承诺永远不会被解决(没有代码可以解决它)。因此,它从不调用它的.then()处理程序,这意味着永远不会调用yolo()函数,这意味着永远不会解析外部承诺。所以,它只是永远停滞不前。

您可以通过在第一个setTimeout()中解析内部承诺来解决这个问题,然后这仍然会使第二个setTimeout()与整个承诺链断开连接。

您可以像这样重写returnapromise()

function delay(t, val) {
    return new Promise(function(resolve) {
        setTimeout(function() {
            console.log(val);
            resolve(val);
        }, t);
    });
}

// function that returns a promise
var returnapromise = function() {
    return delay(200, "async function within nested promise").then(function() {
        return delay(100, "async function within then one");
    }).then(function() {
        return delay(50, "async function within then two");
    });
}; // eof returnapromise()

工作演示:https://jsfiddle.net/jfriend00/k1q60Lep/