为什么Javascript的承诺解析是乱序的?
Why are Javascript promises resolving out of order?
我试图在一个项目中使用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
.then()
需要一个函数引用。当你做这样的事情时:
.then(testPromises(2))
立即执行函数testPromise()
并将返回值传递给.then()
。这几乎从来都不是你想要的(除非testPromises()
返回另一个函数),因为.then()
做它的工作,你必须传递给它一个函数引用(一个函数,它可以在以后的某个时候调用)。如果你立即执行这个函数,那么.then()
就不能完成它的工作,以后再调用它。
相反,你想要的是:
.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()
创建一个curry包装器,它将返回另一个函数。这实际上就是上面的.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');
});
这是获得所需输出的代码:
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');
});
承诺是异步解析的,但是同步创建的。
testPromises(1).then(testPromises(2)).then(testPromises(3))
和
差不多p1 = testPromises(1)
p2 = testPromises(2)
p3 = testPromises(3)
p1.then(p2).then(p3)
由于new Promise
是同步的,您将看到的前三行将是
handling promise 1
handling promise 2
handling promise 3
嗯,
handling promise 1
handling promise 2
handling promise 3
首先出现,因为这些调用独立于Promise工作流,它们在创建每个Promise
对象时执行,因为要这样做,您需要显式执行每个函数,如testPromises(1)
等。
但是问题是你对console.log('all promises resolved');
的调用只依赖于testPromises(1)
被解决,所有其他的承诺都是分离的。
为了同步它们,每个.then
调用必须返回一个Promise,你可以通过使用function
并返回testPromises
函数已经返回的Promises来做到这一点。
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');
});
- JavaScript承诺-无法读取属性'那么'的未定义
- JavaScript承诺的定义以及与事件的区别
- 当链接javascript承诺时,如何处理then()函数中的条件
- 对javascript承诺的后备支持
- 同步 Javascript 承诺超时以加班 Google 地理编码查询限制
- 执行一系列 Javascript 承诺一个接一个地解决
- 如何在恢复函数之前等待 JavaScript 承诺解析
- 用Javascript承诺包装同步代码有什么好处吗
- javascript承诺在循环中或如何逐个调用函数
- Javascript承诺:then()'s是't同步
- Javascript承诺-检索结果
- JavaScript承诺使用Mongoose
- javascript承诺和未来类似于C++
- Javascript承诺并更新变量
- Javascript承诺动态回调
- 具有JavaScript承诺的多个函数
- Javascript承诺:它们能在用户空间代码中完全实现吗
- 如何链接javascript承诺和错误
- Javascript-承诺保留为挂起状态
- 以处理错误的方式启动javascript承诺蓝鸟链