根据B站UP主奇乐编程学院的视频异步编程: 一次性搞懂 Promise, async, await (#js #javascript)做的笔记
前提知识:一个视频告诉你“并发、并行、异步、同步”的区别
一、简介
JavaScript目前有两种实现异步的方式:传统的回调函数CallBack Function以及异步API
二、回调函数CallBack Function
例子:
setTimeout (() => {
console.log("兄弟你好");
}, 3000 );
console.log("你会立刻看到我的");
上面代码中的setTimeout 部分会立刻返回,再执行后面的代码。等到预定的时间后setTimeout 里面的部分才会继续执行 JavaScript从设计之初就是单线程的编程语言。所以上面的代码是在同一个主线程中运行的
缺点:回调地狱CallBack Hell
setTimeout (() => {
console.log("等三秒后");
setTimeout(() => {
console.log("再等三秒");
setTimeout(() => {
console.log("又等三秒");
} ,3000)
}, 3000)
}, 3000 );
三、Promise
Promise 承诺这一请求在未来的某个时刻会返回数据 优点:链式编译chaining ,减少循环嵌套
fetch("https://jsonplaceholder.typicode.com/posts/1")
.then((response)=> response.json())
.then((json) => console.log(json));
错误处理:附加一个catch 在链式结构的末尾,若之前任意一个阶段发生错误,则catch 将会触发,而之后的then() 将不会被执行
fetch("https://jsonplaceholder.typicode.com/posts/1")
.then((response)=> response.json())
.then((json) => console.log(json))
.catch((error) => {
console.log(error);
});
Promise 还提供finally 方法,会在Promise 链结束之后调用,无论失败与否
fetch("https://jsonplaceholder.typicode.com/posts/1")
.then((response)=> response.json())
.then((json) => console.log(json))
.catch((error) => {
console.log(error);
})
.finally(() => {
})
四、async / await
基于Promise 之上的语法糖
async function fun() {
const response = await fetch("https://jsonplaceholder.typicode.com/posts/1");
}
fun()
async 关键字将函数标记为异步函数(返回值为Promise 对象的函数),在异步函数中可以await 语法用来调用异步函数。await 会等待Promise 完成之后直接返回最终的结果。这是因为await 底层是基于Promise 和事件循环Event Loop机制实现的
await便用时的陷阱
- 这样写会破坏两个
fetch 之间的并行关系
async function fun() {
const a = await fetch("https://jsonplaceholder.typicode.com/posts/1");
const b = await fetch("https://jsonplaceholder.typicode.com/posts/2");
}
应该改为:
async function fun() {
const promiseA = await fetch("https://jsonplaceholder.typicode.com/posts/1");
const promiseB = await fetch("https://jsonplaceholder.typicode.com/posts/2");
const [a, b] = await Promise.all([promiseA, promiseB]);
}
- 如果在循环中执行异步操作,是不能够直接调用
forEach 或者map 这一类方法的,尽管我们在回调函数中写了await ,但这里的forEach 会立刻返回,它并不会暂停等到所有异步操作都执行完毕。这种情况就得采用传统的for循环
async function fun() {
[1, 2, 3].forEach(async (i) => {
await someAyncOperation();
});
console.log("done");
}
- 若想要循环中的所有操作都并发执行,可以用
for await ,这里的 for 循环依然会等到所有的异步操作都完成之后才继续向后执行
async function fun() {
const promises = [
someAsyncoperation(),
someAsyncQperation(),
someAsyncleration(),
];
for await (let result of promises) {
}
console.log( "done ");
}
- 不能在全局或者普通函数中直接使用
await 关键字,await 只能被用在异步函数(async function) 中
|