我正在尝试在项目中使用JavaScript承诺,并且事件的顺序是意外的。我已经使用测试承诺将其缩小为一个小型演示。
testPromises = function(promiseNum){
return new Promise(function(resolve, reject) {
console.log ('handling promise '+promiseNum);
setTimeout(function(){
console.log("resolving testPromises "+promiseNum);
resolve();
},2000)
});
};
然后我这样称呼它:
testPromises(1).then(testPromises(2)).then(testPromises(3))
.then(function(value) {
console.log('all promises resolved');
}, function(reason) {
console.log('some promise was rejected');
});
这是控制台输出:
handling promise 1
handling promise 2
handling promise 3
resolving testPromises 1
all promises resolved
resolving testPromises 2
resolving testPromises 3
如何获得输出:
handling promise 1
resolving testPromises 1
handling promise 2
resolving testPromises 2
handling promise 3
resolving testPromises 3
all promises resolved
答案 0 :(得分:5)
.then()
需要一个函数引用。当你做这样的事情时:
.then(testPromises(2))
您正在立即执行函数testPromise()
并将返回值传递给.then()
。这几乎不是你想要的(除非testPromises()
返回另一个函数)。
相反,你想要的是这个:
.then(function() {
return testPromises(2);
})
或者,您可以使用.bind()
:
.then(testPromises.bind(null, 2))
所以,你的整个链看起来像这样:
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');
});
或者,使用.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');
});
如果您经常这样做,可以为testPromises()
制作一个可以返回另一个函数的咖喱包装器。这基本上就是上面.bind()
所做的事情,但是一旦你声明了你的包装函数,语法就会更加漂亮。
function tp(arg) {
return function() {
return testPromises(arg);
}
}
然后,因为该包装器返回另一个函数,所以你可以这样做:
testPromises(1).then(tp(2)).then(tp(3))
.then(function(value) {
console.log('all promises resolved');
}, function(reason) {
console.log('some promise was rejected');
});
答案 1 :(得分:2)
这是获取所需输出的代码:
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');
});
Promise 异步解析,但同步创建。
testPromises(1).then(testPromises(2)).then(testPromises(3))
或多或少喜欢做
p1 = testPromises(1)
p2 = testPromises(2)
p3 = testPromises(3)
p1.then(p2).then(p3)
由于new Promise
是同步的,您将看到的前3行将是
handling promise 1
handling promise 2
handling promise 3
答案 2 :(得分:0)
那么,
handling promise 1
handling promise 2
handling promise 3
首先发生,因为这些调用独立于Promise工作流,它们在您创建每个Promise
对象时立即执行,因为这样做可以显式执行每个函数,如testPromises(1)
等等。 / p>
但问题是,您对console.log('all promises resolved');
的调用仅取决于testPromises(1)
正在解决,所有其他承诺都已分离。
为了同步它们,每个.then
调用必须返回一个Promise,你可以使用function
并返回Promises testPromises
函数已经返回。
testPromises = function(promiseNum){
return new Promise(function(resolve, reject) {
console.log ('handling promise '+promiseNum);
setTimeout(function(){
console.log("resolving testPromises "+promiseNum);
resolve();
},0)
});
};
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');
});