likes
comments
collection
share

JS 异步打印结果,Are you 会?

作者站长头像
站长
· 阅读数 52

前言

console.log('script start');

setTimeout(() => {
    console.log('time1');
}, 1 * 2000);

Promise.resolve()
.then(function() {
    console.log('promise1');
}).then(function() {
    console.log('promise2');
});


async function foo() {
    await bar()
    console.log('async1 end')
}
foo()

async function errorFunc () {
    try {
        await Promise.reject('error!!!')
    } catch(e) {
        console.log(e)
    }
    console.log('async1');
    return Promise.resolve('async1 success')
}
errorFunc().then(res => console.log(res))

function bar() {
    console.log('async2 end') 
}

console.log('script end');

打印顺序如下,我对打印结果不能理解,文章也没有详细解析。于是引发了一连串的测试和思考。

script start
async2 end
script end
promise1
async1 end
error!!!
async1
promise2
async1 success
time1

参考最简单的案例

setTimeout(() => {
  console.log(1);
}, 1000)
new Promise(function(resolve){
    console.log(2);
    for(var i = 0; i < 10000; i++){
        i == 99 && resolve();
    }
}).then(function(){
    console.log(3)
});
console.log(4)

JS 异步打印结果,Are you 会?

打印顺序为:

2
4
3
1

疑问1: 多个连续的 then 如何打印

如果then后面还有多个then呢?这多个then同属于微任务是不是要一起先于setTimeout宏任务执行,答案:是的。

setTimeout(() => {
  console.log(1)
}, 1000)
new Promise(function (resolve) {
  console.log(2)
  for (var i = 0; i < 10000; i++) {
    i == 99 && resolve()
  }
})
  .then(function () {
    console.log(3)
  })
  .then(function () {
    console.log(33)
  })
  .then(function () {
    console.log(333)
  })
console.log(4)

打印结果:

2
4
3
33
333
1

疑问2: async await 怎么处理

setTimeout(() => {
  console.log(1)
}, 1000)
new Promise(function (resolve) {
  console.log(2)
  for (var i = 0; i < 10000; i++) {
    i == 99 && resolve()
  }
})
  .then(function () {
    console.log(3)
  })
  .then(function () {
    console.log(33)
  })
  .then(function () {
    console.log(333)
  })
async function foo () {
  console.log('foo1')
  await bar()
  console.log('foo2')
}
function bar () {
  console.log('bar')
}
foo()
console.log(4)

这里需要知道,await 执行的这句是同步执行的,await 后面执行的是微任务。

2
foo1
bar
4
3
foo2
33
333
1

另外还要知道,多个微任务之间也会有先后顺序,如上可以看到,foo23 之后,但在 33333 之前。

可想而知,如果 await 也有多个,那顺序是上下上下的那种,即每个微任务都先跑第一个,然后各自的第二个,以此类推。

验证如下:

setTimeout(() => {
  console.log(1)
}, 1000)
new Promise(function (resolve) {
  console.log(2)
  for (var i = 0; i < 10000; i++) {
    i == 99 && resolve()
  }
})
  .then(function () {
    console.log(3)
  })
  .then(function () {
    console.log(33)
  })
  .then(function () {
    console.log(333)
  })
async function foo () {
  console.log('foo1')
  await bar()
  await bar2()
  await bar3()
  console.log('foo2')
}
function bar () {
  console.log('bar')
}
function bar2 () {
  console.log('bar2')
}
function bar3 () {
  console.log('bar3')
}
foo()
console.log(4)

打印如下:

2
foo1
bar
4
3
bar2
33
bar3
333
foo2
1

画个草图:

JS 异步打印结果,Are you 会?

疑问3: async 返回了什么,.then 会怎样?

先来个简单的:

console.log('script start')
async function foo () {
  console.log('foo1')
  await 2
  console.log('foo2')
}
foo()
console.log('script end')

打印:

script start
foo1
script end
foo2

增加 .then:

console.log('script start')
async function foo () {
  console.log('foo1')
  await 2
  console.log('foo2')
  return 'foo3'
}
foo()
  .then(res => {
    console.log(res)
    console.log('then1')
  })
  .then(res => {
    console.log(res)
    console.log('then2')
  })
console.log('script end')

得到:

script start
foo1
script end
foo2
foo3
then1
undefined
then2

重新开开头的题目

console.log('script start')

setTimeout(() => {
  console.log('time1')
}, 1)

Promise.resolve()
  .then(function () {
    console.log('promise1')
  })
  .then(function () {
    console.log('promise2')
  })

async function foo () {
  await bar()
  console.log('async1 end')
}
foo()

async function errorFunc () {
  try {
    await Promise.reject('error!!!')
  } catch (e) {
    console.log(e)
  }
  console.log('async1')
  return Promise.resolve('async1 success')
}
errorFunc().then(res => console.log(res))

function bar () {
  console.log('async2 end')
}

console.log('script end')

JS 异步打印结果,Are you 会?

得到:

script start
async2 end
script end
promise1
async1 end
error!!!
async1
promise2
async1 success
time1

good 完全吃透了!

来巩固一下

console.log('script start')
setTimeout(() => {
  console.log('timeout')
}, 0)
Promise.resolve()
  .then(() => {
    console.log('then1')
  })
  .then(() => {
    console.log('then1')
  })
  .then(() => {
    console.log('then1')
  })
const p1 = new Promise((resolve, reject) => {
  console.log('p1')
  setTimeout(() => {
    resolve()
    console.log('p1-timeout')
  }, 0)
})
p1.then(() => {
  console.log('p1-then')
})
const p2 = new Promise((resolve, reject) => {
  console.log('p2')
  setTimeout(() => {
    resolve()
    console.log('p2-timeout')
  }, 0)
})
p2.then(() => {
  console.log('p2-then')
})
Promise.resolve()
  .then(() => {
    console.log('then2')
  })
  .then(() => {
    console.log('then2')
  })
  .then(() => {
    console.log('then2')
  })
console.log('script end')

打印:

script start
p1
p2
script end
then1
then2
then1
then2
then1
then2
timeout
p1-timeout
p1-then
p2-timeout
p2-then

JS 异步打印结果,Are you 会?

转载自:https://juejin.cn/post/7047491986567217182
评论
请登录