×

大神请指教下setTimeOut,Promise, async await的区别

提问者:航海博客2023.07.21浏览:1658

考察这三者在事件循环中的区别,事件循环中分为宏任务队列和微任务队列。

1. settimeout的回调函数放到宏任务队列里,等到执行栈清空以后执行;

2. promise.then里的回调函数会放到微任务队列里,等宏任务里面的同步代码执行完再执行;

3. async 函数返回一个 Promise 对象,当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再执行函数体内后面的语句。可以理解为,是让出了线程,跳出了 async 函数体。

Promise

对象用于表示一个异步操作的最终完成(或失败), 及其结果值.

promise 的方法

Promise.resolve(value)

返回一个状态由给定value决定的Promise对象。

1. 如果传入的 value 本身就是 Promise 对象,则该对象作为 Promise.resolve 方法的返回值返回。

2. 如果该值是thenable(即,带有then方法的对象),返回的Promise对象的最终状态由then方法执行决定

3. 其他情况,返回一个状态已变成 resolved 的 Promise 对象。

Promise.reject

类方法,且与 resolve 唯一的不同是,返回的 promise 对象的状态为 rejected。

Promise.all

类方法,多个 Promise 任务同时执行。

如果全部成功执行,则以数组的方式返回所有 Promise 任务的执行结果。 如果有一个 Promise 任务 rejected,则只返回 rejected 任务的结果。

Promise.race

类方法,多个 Promise 任务同时执行,返回最先执行结束的 Promise 任务的结果,不管这个 Promise 结果是成功还是失败。

其他

实例方法:

+ Promise.prototype.then 为 Promise 注册回调函数

Promise.prototype.catch 实例方法,捕获异常

Promise 状态

Promise 对象有三个状态,并且状态一旦改变,便不能再被更改为其他状态。

pending,异步任务正在进行。

resolved(也可以叫fulfilled),异步任务执行成功。

rejected,异步任务执行失败

使用总结

首先初始化一个 Promise 对象,可以通过两种方式创建,这两种方式都会返回一个 Promise 对象。

1、new Promise(fn)

2、Promise.resolve(fn)

然后调用上一步返回的 promise 对象的 then 方法,注册回调函数。最后注册 catch 异常处理函数,

Promise All 实现

接收一个 Promise 实例的数组或具有 Iterator 接口的对象,

如果元素不是 Promise 对象,则使用 Promise.resolve 转成 Promise 对象

如果全部成功,状态变为 resolved,返回值将组成一个数组传给回调

只要有一个失败,状态就变为 rejected,返回值将直接传递给回调

Promise.all() 的返回值也是新的 Promise 对象

Async / Await内部实现

async 做了什么

async 函数会返回一个 Promise 对象,如果在函数中 return 一个直接量,async 会把这个直接量通过 Promise.resolve() 封装成 Promise 对象。

await 在等啥

await 可以用于等待一个 async 函数的返回值,注意到 await 不仅仅用于等 Promise 对象,它可以等任意表达式的结果,所以,await 后面实际是可以接普通函数调用或者直接量的。

await 等到了要等的,然后呢

如果它等到的不是一个 Promise 对象,那 await 表达式的运算结果就是它等到的东西。

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

async / await 优势在哪?

async / await 的优势在于处理 then 链,尤其是每一个步骤都需要之前每个步骤的结果时,async / await 的代码对比promise非常清晰明了,简直像同步代码一样。

实现原理

async / await 就是 Generator 的语法糖,使得异步操作变得更加方便。async 函数就是将 Generator 函数的星号(*)替换成 async,将 yield 替换成await。

不一样的是:

async函数内置执行器,函数调用之后,会自动执行,输出最后结果。而Generator需要调用next。

返回值是Promise,async函数的返回值是 Promise 对象,Generator的返回值是 Iterator(迭代器),Promise 对象使用起来更加方便。

简单实习代码:

function asyncToGenerator(generatorFunc) {
return function() {
// 先调用generator函数 生成迭代器
const gen = generatorFunc.apply(this, arguments)
return new Promise((resolve, reject) => {
function step(key, arg) {
let generatorResult
try {
generatorResult = gen[key](arg)
} catch (error) {
return reject(error)
}
const { value, done } = generatorResult
if (done) {
return resolve(value)
} else {
return Promise.resolve(
value
).then(
function onResolve(val) {
step("next", val)
},
function onReject(err) {
step("throw", err)
},
)
}
}
step("next")
})
}
}

您的支持是我们创作的动力!

网友回答文明上网理性发言 已有0人参与

发表评论: