最近有点水,还是直接记录不知道的算了......
第十一章 期约与异步函数
最开始的异步是回调,逻辑越复杂,回调越复杂,因此产生了“回调地狱”
期约
期约,就是 Promise
使用:
let promise = new Promise((resolve,reject) => {})
通过控制台打印,此时的 promise 状态是 pending(待定);使用 resolve() 将状态改为 fulfilled(兑现 / resolved 解决);使用 reject() 将状态改为 rejected(拒绝)
API
- then
- catch
- finally
一般像 then,需要两个回调函数来表示成功或接收失败,而 finally 可以直接获取两者的回调 - all
通过 all 调用的期约会在所有期约都处理完后一起返回 - race
通过 race 调用的期约会在第一个期约处理完后立即返回,无论兑现或拒绝
异步函数
async 用于声明异步函数,默认情况下的 return 是被 Promise.resolve 包装过的,属于异步返回
await 只能使用在声明了 async 的环境中
实现 sleep()
async function sleep(delay) {
return new Promise((resolve) => setTimeout(resolve, delay));
}
async function foo() {
const t0 = Date.now();
await sleep(1500); // 暂停约1500毫秒
console.log(Date.now() - t0);
}
foo();
// 1502
平行执行
期约之间没有依赖,异步函数也会依次暂停,等待每个超时完成。这样可以保证执行顺序,但总执行时间会变长。如果顺序不是必需保证的,那么可以先一次性初始化所有期约,然后再分别等待它们的结果。
async function randomDelay(id) {
// 延迟0~1000毫秒
const delay = Math.random() * 1000;
return new Promise((resolve) => setTimeout(() => {
console.log(`${id} finished`);
resolve();
}, delay));
}
async function foo() {
const t0 = Date.now();
const promises = Array(5).fill(null).map((_, i) => randomDelay(i));
for (const p of promises) {
await p;
}
console.log(`${Date.now() - t0}ms elapsed`);
}
foo();
// 4 finished
// 2 finished
// 1 finished
// 0 finished
// 3 finished
// 877ms elapsed
网友评论