我试图理解Promise /异步编程,但我不理解为什么这段代码显示“ 1 2 0”而不是“ 2 1 0”。从第三段代码开始:f1不应仅在f2将“ 2”记录到控制台后才触发?
const f1 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(console.log(1));
}, 1000)
})
const f2 = new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve(console.log(2))
}, 1500)
})
f2.then(
f1.then(()=>{
setTimeout(()=>{
console.log(0);
}, 500)}
));
我正在尝试一个程序,该程序需要几个(如6ish)异步函数以非常特定的顺序触发,即f2()必须等到f1()完全接收到来自执行请求的数据后,我我实际上不确定该怎么做...
答案 0 :(得分:0)
您正在并行运行f1和f2操作,一个接一个地启动它们。两者都开始,然后它们同时在飞行中。
然后,您需要将函数引用传递给.then()
,以便该函数可以在将来某个时间(当主机Promise解析时)调用Promise基础结构。相反,您是向.then()
传递了一个诺言,这没有任何用处。
如果您将代码更改为此:
const f1 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(console.log(1));
}, 1000)
})
const f2 = new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve(console.log(2))
}, 1500)
})
f2.then(() => {
f1.then(()=> {
setTimeout(()=>{
console.log(0);
}, 500)}
});
});
然后,您将立即启动f1和f2计时器。然后,只有在f2和f1都完成之后,您才启动第三个计时器,并且应该获得输出1 2 0
。 1
之所以排在第一位,是因为它的计时器比2
短,它们都是并行运行的。 0
之所以排在最后,是因为直到1
和2
都完成后,计时器才开始计时。
如果要链接它们以获得2 1 0
,则不必同时启动2
和1
。使f1和f2成为函数,而不是诺言,以便您可以在调用它们时进行排序。
function delay(t) {
return new Promise(resolve => {
setTimeout(resolve, t);
});
}
function f1() {
return delay(1000).then(() => {
console.log(1);
})
}
function f2() {
return delay(1500).then(() => {
console.log(2);
})
}
function f3() {
return delay(1500).then(() => {
console.log(0);
})
}
// chain them together
f2().then(f1).then(f3).then(() => {
console.log("done");
});
这种.then()
链接基本上是这样说的:
f2()
.then()
返回的诺言上注册.f2()
处理程序,以便当该诺言得到解决时,它将(且仅在此之后)调用f1。f2().then()
返回的新承诺,在其上注册.then()
处理程序,以便在f1完成后将调用f3。f2().then().then()
返回的新承诺,注册一个在f3完成后将被调用的回调。