简体   繁体   English

为什么我的代码按此顺序打印? (JavaScript承诺)

[英]Why does my code print in this sequence? (Javascript promises)

I'm trying to understand promises/asynchronous programming, and I don't understand why this code prints "1 2 0" rather than "2 1 0". 我试图理解Promise /异步编程,但我不理解为什么这段代码显示“ 1 2 0”而不是“ 2 1 0”。 From the third block of code: shouldn't f1 fire only after f2 logs "2" to the console? 从第三段代码开始: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)}
));

I'm trying to work on a program that needs several (like 6ish) asynchronous functions to fire in a very specific sequence, ie f2() must wait until f1() fully receives data from a request to execute, and I'm actually not sure how to do this... 我正在尝试一个程序,该程序需要几个(如6ish)异步函数以非常特定的顺序触发,即f2()必须等到f1()完全接收到来自执行请求的数据,而我实际上是不知道该怎么做...

You are running your f1 and f2 operations in parallel, starting them both one after the other. 您正在并行运行f1和f2操作,一个接一个地启动它们。 Both are started and then they are both in flight at the same time. 两者都开始,然后它们同时在飞行中。

Then, you need to pass a function reference to .then() so it's a function that the promise infrastructure can call sometime in the future (when the host promise resolves). 然后,您需要将函数引用传递给.then()以便promise基础结构可以在将来的某个时间(当主机promise解析时)调用该函数。 Instead, you are passing a promise to .then() which doesn't do anything useful. 相反,您向.then()传递了一个承诺.then()该承诺没有任何用处。

If you change your code to this: 如果将代码更改为此:

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)}
  });
});

Then, you will start both the f1 and f2 timers immediately. 然后,您将立即启动f1和f2计时器。 Then, only after both f2 and f1 finish will you start the third timer and you should get the output 1 2 0 . 然后,只有在f2和f1都完成之后,您才启动第三个计时器,并且应该获得输出1 2 0 1 comes first because it's a shorter timer than 2 which are both running in a parallel. 1之所以排在第一位,是因为它的计时器比2都并行运行的计时器短。 0 comes last because it's timer isn't started until both 1 and 2 are done. 0在最后,因为直到12都完成后,计时器才启动。


If you want to chain them to get 2 1 0 , then you have to not start 2 and 1 at the same time. 如果要链接它们以获得2 1 0 ,则不必同时启动21 Make f1 and f2 into functions, not promises so you can sequence when they are called. 使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"); }); 

This kind of .then() chaining basically says this: 这种.then()链接基本上是这样说的:

  • Execute f2() 执行f2()
  • Register a .then() handler on the promise that .f2() returns so that when that promise resolves, it will then (and only then) call f1. .f2()返回的promise上注册一个.then()处理程序,以便该promise解析后,它将(且仅在此之后)调用f1。
  • On the new promise that f2().then() returns, register a .then() handler on it so that when f1 is done, it will then call f3. 根据f2().then()返回的新承诺,在其上注册一个.then()处理程序,以便在f1完成后将调用f3。
  • On the new promise that f2().then().then() returns, register a callback that will be called when f3 is done. 根据f2().then().then()返回的新承诺,注册一个回调,当f3完成时将调用该回调。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM