哔哩哔哩:JS 异步笔试题,请写出以下代码的执行结果

202次阅读  |  发布于3年以前
var date = new Date() 

console.log(1, new Date() - date) 

setTimeout(() => {
    console.log(2, new Date() - date)
}, 500) 

Promise.resolve().then(console.log(3, new Date() - date)) 

while(new Date() - date < 1000) {} 

console.log(4, new Date() - date)

求上面的输出顺序和输出值,为什么?

答案:

1 0
3 1
4 1000
2 1000

其中,关于时间差结果可能因为计算机性能造成的微小差异,可忽略不计

你答对了吗?下面我们由浅入深探索本题

由浅入深探索 Promise 异步执行

首先,看一下 event loop 的基础必备内容

event loop 执行顺序:

微任务包括:MutationObserverPromise.then()或catch()Promise为基础开发的其它技术,比如fetch APIV8的垃圾回收过程、Node独有的process.nextTickObject.observe(已废弃;Proxy 对象替代)

宏任务包括scriptsetTimeoutsetIntervalsetImmediateI/OUI renderingpostMessageMessageChannel

注意: 下面的题目都是执行在浏览器环境下

遇到不好理解的,可结合 【promise 源码实现:https://github.com/sisterAn/blog/issues/13】 进行理解,就很简单了

1. 同步 + Promise

题目一:

var promise = new Promise((resolve, reject) => {
    console.log(1)
    resolve()
    console.log(2)
})
promise.then(()=>{
    console.log(3)
})
console.log(4)
// 1
// 2
// 4
// 3

解析:

题目二:

var promise = new Promise((resolve, reject) => {
    console.log(1)
})
promise.then(()=>{
    console.log(2)
})
console.log(3)
// 1
// 3

解析:

题目三:

var promise = new Promise((resolve, reject) => {
    console.log(1)
})
promise.then(console.log(2))
console.log(3)
// 1
// 2
// 3

解析:

题目四:

Promise.resolve(1)
  .then(2)
  .then(Promise.resolve(3))
  .then(console.log)
// 1

解析:

题目五:

var promise = new Promise((resolve, reject) => {
    console.log(1)
    resolve()
    reject()
})
promise.then(()=>{
    console.log(2)
}).catch(()=>{
    console.log(3)
})
console.log(4)
// 1
// 4
// 2

解析:

题目六:

Promise.resolve(1)
  .then(res => {
    console.log(res);
    return 2;
  })
  .catch(err => {
    return 3;
  })
  .then(res => {
    console.log(res);
  });
// 1
// 2

解析:

2. 同步 + Promise + setTimeout

题目一:

setTimeout(() => {
  console.log(1)
})
Promise.resolve().then(() => {
  console.log(2)
})
console.log(3)
// 3
// 2
// 1

解析:

题目二:

var promise = new Promise((resolve, reject) => {
  console.log(1)
  setTimeout(() => {
    console.log(2)
    resolve()
  }, 1000)
})

promise.then(() => {
  console.log(3)
})
promise.then(() => {
  console.log(4)
})
console.log(5)
// 1
// 5
// 2
// 3
// 4

解析:

回到开头

现在看,本题就很简单了

var date = new Date() 

console.log(1, new Date() - date) 

setTimeout(() => {
    console.log(2, new Date() - date)
}, 500) 

Promise.resolve().then(console.log(3, new Date() - date)) 

while(new Date() - date < 1000) {} 

console.log(4, new Date() - date)

解析:

总结

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8