我认为await阻塞线程的说法不正确, 大家讨论一下
来源:2-8 深入理解async和await

GivenCui
2019-06-23
await会暂停当前 async function 的执行,等待 Promise 处理完成, async内是阻塞的, async外是非阻塞的
const mockAsyn = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('等待2秒')
}, 2000)
})
}
const testAsyn = async () => {
console.log('1')
const res = await mockAsyn()
console.log('2', res)
}
testAsyn()
console.log('3')
console.log('4')
// 1
// 3
// 4
// 2 等待2秒
若按照老师的说法, 阻塞了线程, 则结果应为:
// 1
// 2 等待2秒
// 3
// 4
js是单线程的, 如果阻塞了线程, 那么就相当于卡住了, 所以这个说法是不对的
p.s. async function是基于generator的, 根promise没啥关系, 只是一种更好的异步解决方案罢了…
4回答
-
单线程要想实现并发,必须是要分隔到比线程更细粒度的机制上来执行代码,js里就是”任务“。课程这里没有更深入的讲解宏任务和微任务,毕竟不是js语法课,能理解到await的等待就够了。有兴趣的同学可以看看后面的章节的深入讲解,并自行了解下宏任务和微任务。不过感谢指出这个说法,我后面补充下课程,强调下,阻塞线程只是一个便于理解的说法。同学很不错,有自己的思考,继续加油。
212019-06-25 -
7七月
2019-06-24
这个后面有深入的讲解,js有宏任务和微任务的区别。单线程是不可能让线程不工作的,只是会把任务挂起。另外这个基于generator这个就不做解释了,说的不是一个层面的东西,他当然是基于generator的语法糖,但和promise连用才有意义。
322019-06-27 -
灿烂__
2020-03-05
同学 这个其实是eventLoop的相关知识点,只要是异步,都会放到异步进程里,当主线程同步任务执行完毕,任务队列就调取异步的分线程来执行。然后异步event事件队列是先进先出,每个异步都会执行 ,但是异步也分宏任务微任务,setTimeout是宏任务,Promise是微任务,而在async和await中,async是同步进行,函数体内await前面的代码是走同步的,await后面的代码是异步微任务,因为await后面就是promise.then()里的代码,所以js在执行完这次宏任务完成后,会执行相关微任务,再次执行下一次的宏任务,和他所带的微任务,知道异步进程里的任务都被执行完。
理清事件循环之后,回头来看你的问题,首先定义了两个方法,但并未执行,然后执行testAsyn(),1先输出,接着调用了mockAsyn函数,这放到了异步队列里,先不执行,然后再看下一行的console数字2,也是await后面的,也不执行,接着执行同步代码,输出3和4,然后回来看这次执行种牵带着的微任务 mockAsync调用,而在mockAsync种是返回一个宏任务setTimeout,然后放到下一次异步队列中,第一次事件循环完成,然后第二次事件循环,等待两秒,执行之前放入的队列中的宏任务,打印“等待2秒”,因为之前await是有关系到这一次setTimeout的,所以2属于上一次事件循环中的,所以要比setTimeout“等待2秒”先打印。故而顺序是1 3 4 2 等待2秒。
那么为什么2没有先和第一次事件循环一起打印,而要等待2秒呢,那就是因为老师说的await阻塞的线程这个原因。
同学若觉得我没讲清或着有错误的地方,也可以自行查阅有关事件循环eventLoop的相关知识,再来这里告知,大家一起加油~
10 -
苏湘门第
2020-02-09
感谢同学提问,我默默的将你的promise代码敲了一遍,继续看课程,希望会有解答
00
相似问题