每个面试官都会考的:深入理解异步编程

35 阅读3分钟

setTimeout、Promise、Async/Await 的区别

setTimeout执行顺序:

先同步代码再异步代码

Promise执行顺序:

先执行同步代码,再将resolve加入微队列,再执行微队列,再执行宏队列(settimeout会放在宏队列之中)。

Async/Await执行顺序:

await 后面的代码会作为微任务加入微任务队列。所有同步代码执行完毕后,事件循环首先处理微任务队列,然后处理宏任务队列。

对Promise的理解

promise是一个可以接收异步消息的对象,使用统一的api对异步操作进行处理。

Promise的实例有三个状态: ●Pending(进行中) ●Fulfilled(已完成) ●Rejected(已拒绝)

Promise的缺点:

●无法取消Promise,一旦新建它就会立即执行,无法中途取消。(因为promise内部如果要走reject的逻辑或者是resolve的逻辑,就必须要是pending状态才能进去【可以理解为是一个if判断,只有pending能进这个判断】,而一旦进入,pending就会立即被改变,进入的是哪个逻辑就改成哪个逻辑应对的fulfilled或者是rejected,然后再也不能再进入另一个了)

●如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。

●当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)

Promise方法

resolved()调用成功的回调

rejected()调用失败的回调

then()状态改变时调用,第一个参数处理成功的回调,第二个参数处理失败的回调

catch()捕获异常,它是 .then() 方法的一种简写形式,专门用于处理 Promise 对象在执行过程中发生的错误。

finally。finally 方法用于指定不管 Promise 对象最终的状态如何,都会执行的回调函数

all()用于将多个 Promise 对象包装成一个新的 Promise 对象。当所有的 Promise 对象都变为 Fulfilled 或其中有一个变为 Rejected 时,新的 Promise 对象的状态才会发生改变。

race()Promise.race 用于将多个 Promise 对象包装成一个新的 Promise 对象。新的 Promise 对象的状态将跟随第一个状态发生变化的 Promise 对象。

对async/await 的理解

async/await其实是Generator 的语法糖,它是为优化then链而开发出来的。

在最外层不能用 await 获取其返回值的情况下,用then() 链来处理这个 Promise 对象:

async function testAsy(){
   return 'hello world'
}
let result = testAsy() 
console.log(result)
result.then(v=>{
    console.log(v)   // hello world
})

await 到底在等啥?

在等任意表达式的返回结果

如果等到的不是一个 Promise 对象,那 await 表达式的运算结果就是它等到的东西。 如果它等到的是一个 Promise 对象,await 就忙起来了,它会阻塞后面的代码,等着 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。

await 必须用在 async 函数中的原因

async 函数本身就是用来处理异步操作的。如果在非异步函数中使用 await,会导致阻塞整个线程,造成程序的停滞,违背了 JavaScript 的单线程执行模型。