首页 > 解决方案 > Javascript、Promises 和 setTimeout

问题描述

我一直在玩 Promises,但我无法理解以下代码发生了什么:

const promise = new Promise((resolve, reject) => {
  console.log('Promise started - Async code started')
  setTimeout(() => {
    resolve('Success')
  }, 10)
})

setTimeout(() => {
  console.log('Promise log inside first setTimeout')
}, 0)

promise.then(res => {
  console.log('Promise log after fulfilled')
})

console.log('Promise made - Sync code terminated')

setTimeout(() => {
  console.log('Promise log inside second setTimeout')
}, 0)

输出是:


Promise started - Async code started 
Promise made - Sync code terminated 
Promise log inside first setTimeout 
Promise log inside second setTimeout 
Promise log after fulfilled

正如预期的那样。

但是让我们检查以下代码的输出:

const promise = new Promise((resolve, reject) => {
  console.log('Promise started - Async code started')
  setTimeout(() => {
    resolve('Success')
  }, 1)
})

setTimeout(() => {
  console.log('Promise log inside first setTimeout')
}, 0)

promise.then(res => {
  console.log('Promise log after fulfilled')
})

console.log('Promise made - Sync code terminated')
setTimeout(() => {
  console.log('Promise log inside second setTimeout')
}, 0)

将要解决的承诺 setTimeout 计时器值从 10 毫秒更改为 1 毫秒

输出是:

Promise started - Async code started 
Promise made - Sync code terminated 
Promise log after fulfilled 
Promise log inside first setTimeout 
Promise log inside second setTimeout 

对此有何解释?

标签: javascriptgoogle-chromepromisesettimeoutes6-promise

解决方案


来自并发模型和事件循环

  • setTimeout计时器到期后不会立即运行
  • 零延迟实际上并不意味着回调将在零毫秒后触发。延迟为 0(零)毫秒的调用setTimeout不会在给定时间间隔后执行回调函数。 基本上,setTimeout即使您为 setTimeout 指定了特定的时间限制,也需要等待排队消息的所有代码完成。

如果我们设置 2 和 1 毫秒会发生什么:

const promise = new Promise((resolve, reject) => {
  console.log('Promise started - Async code started')
  setTimeout(() => {
    resolve('Success')
  }, 2)
})

console.log('Promise log inside first setTimeout 1')
setTimeout(() => {
  console.log('Promise log inside first setTimeout 2')
}, 1)

promise.then(res => {
  console.log('Promise log after fulfilled ❌')

})

console.log('Promise log inside second setTimeout 1')
setTimeout(() => {
  console.log('Promise log inside second setTimeout 2')
}, 1)
});

输出总是:

Promise started - Async code started
Promise log inside first setTimeout 1
Promise log inside second setTimeout 1
Promise log inside first setTimeout 2
Promise log inside second setTimeout 2
Promise log after fulfilled ❌

结论

如果你想要一个正确的行为,值得摆脱零延迟。


推荐阅读