【问题标题】:Weird Behavior from Console.log() in promises承诺中来自 Console.log() 的奇怪行为
【发布时间】:2020-01-23 01:10:33
【问题描述】:

所以当我在 promise 中使用 console.log() 时,我正在使用 promises 做一些工作并得到一些奇怪的行为。

代码

function doSomething(msg){ 
      return new Promise(
        (myresolve, myreject) => {
          setTimeout(
             () => {
              console.log(msg);
              console.log('In the promise')
              myresolve();
            }, 
            1000);
        }); 
    }



   doSomething("1st Call")
  .then(function() {
    doSomething("2nd Call");
    console.log('leaving 2nd promise'); 
  })
  .then(function() {
    doSomething("3rd Call");
    console.log('leaving 3rd promise');
}); 

输出到控制台

  • '第一次通话'
  • '在承诺中'
  • '留下第二个承诺'
  • '离开第三个承诺'
  • '第二次通话'
  • '在承诺中'
  • '第三次通话'
  • '在承诺中'

主要问题 为什么 JavaScript 在 Promise 中似乎没有按顺序读取代码行一次?几乎看起来它是先通过并首先进行控制台日志记录,然后返回代码并执行承诺在 .then 方法之后执行的函数。任何见解将不胜感激...

【问题讨论】:

  • 这是我希望看到的输出。为了帮助回答您的问题,您能否明确列出您期望的确切输出,以便我们解释差异?
  • 我想你还没有考虑到超时造成的延迟。附言您日志中的短语leaving 2nd promiseleaving 3rd promise 并不准确。它们在附加到 1st 承诺的 .then() 回调中。它们不依赖于执行的第二个和第三个承诺。第二个和第三个承诺只会显示2nd call / 3rd callIn the promise
  • setTimeout 中的代码要到稍后才会运行 - 顺序没有问题 - ...如果你把 var ret = doSomething('2nd Call')return ret 放在 console.log('leaving... 之后,你会更接近您期望的订单
  • 这与您设置的延迟有关。如果您立即解决它,您可以看到它保持正确的顺序。
  • 如果你的 .then() 回调返回了从 doSomething() 返回的 Promise 实例,结果会略有不同,但有趣的是。

标签: javascript promise console.log


【解决方案1】:
doSomething("2nd Call");
console.log('leaving 2nd promise'); 

做某事是异步的,需要~1000 m/s 来完成它的执行。因此,当最初调用 doSomething("2nd Call"); 时,您的代码会跳转到您的方法中,返回 promise,然后开始 setTimeout。然后,"leaving 2nd promise" 被记录。稍后,我们之前通过调用doSomething("2nd Call") 启动的setTimeout 将完成,因此它将"2nd Call" 记录到控制台。要等待您对doSomething("2nd Call") 的初始调用完成,您需要在它返回的promise 上使用.then()(或await),这样您就可以在promise 解决时执行您的代码:

function doSomething(msg) {
  return new Promise(
    (myresolve, myreject) => {
      setTimeout(
        () => {
          console.log(msg);
          console.log('In the promise')
          myresolve();
        },
        1000);
    });
}



doSomething("1st Call")
  .then(() => doSomething("2nd Call"))
  .then(() => console.log('leaving 2nd promise'))
  .then(() => doSomething("3rd Call"))
  .then(() => console.log('leaving 3rd promise'));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-06
    • 2012-08-09
    • 2020-02-10
    • 2014-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多