为什么Javascript承诺无法解决?

ama*_*ack 3 javascript promise

我试图在项目中使用JavaScript promise,事件的顺序是意外的.我已经使用测试承诺将其缩小为一个小型演示.

testPromises = function(promiseNum){
    return new Promise(function(resolve, reject) {
        console.log ('handling promise '+promiseNum);
        setTimeout(function(){
            console.log("resolving testPromises "+promiseNum);
            resolve();
        },2000)
    });
};
Run Code Online (Sandbox Code Playgroud)

然后我这样称呼它:

testPromises(1).then(testPromises(2)).then(testPromises(3))
.then(function(value) {
        console.log('all promises resolved');
}, function(reason) {
        console.log('some promise was rejected');
});
Run Code Online (Sandbox Code Playgroud)

这是控制台输出:

handling promise 1
handling promise 2
handling promise 3
resolving testPromises 1
all promises resolved
resolving testPromises 2
resolving testPromises 3
Run Code Online (Sandbox Code Playgroud)

如何获得输出:

handling promise 1
resolving testPromises 1
handling promise 2
resolving testPromises 2
handling promise 3
resolving testPromises 3
all promises resolved
Run Code Online (Sandbox Code Playgroud)

jfr*_*d00 6

.then()期待一个功能参考.当你做这样的事情:

.then(testPromises(2))
Run Code Online (Sandbox Code Playgroud)

您正在testPromise()立即执行该函数并将返回值传递给.then().这几乎不是你想要的(除非testPromises()返回另一个函数).

相反,你想要的是这个:

.then(function() {
    return testPromises(2);
})
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用.bind():

.then(testPromises.bind(null, 2))
Run Code Online (Sandbox Code Playgroud)

所以,你的整个链看起来像这样:

testPromises(1).then(function() {
    return testPromises(2);
}).then(function() {
    return testPromises(3);
}).then(function(value) {
    console.log('all promises resolved');
}, function(reason) {
    console.log('some promise was rejected');
});
Run Code Online (Sandbox Code Playgroud)

或者,使用 .bind()

testPromises(1)
  .then(testPromises.bind(null, 2))
  .then(testPromises.bind(null, 3))
  .then(function(value) {
        console.log('all promises resolved');
  }, function(reason) {
        console.log('some promise was rejected');
  });
Run Code Online (Sandbox Code Playgroud)

如果你正在做这么多,你可以做一个咖喱包装,testPromises()这将返回另一个功能.这基本上就是.bind()上面所做的,但是一旦你声明了你的包装函数,语法就会更加漂亮.

function tp(arg) {
    return function() {
        return testPromises(arg);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,因为该包装器返回另一个函数,您可以这样做:

testPromises(1).then(tp(2)).then(tp(3))
.then(function(value) {
    console.log('all promises resolved');
}, function(reason) {
    console.log('some promise was rejected');
});
Run Code Online (Sandbox Code Playgroud)