在学习async和await之前需要掌握promise。
目的:
异步编程,同步写法
让我们以同步的方式处理异步的流程,同时不会阻塞主线程
使用规则:
- 凡是在前面添加了async的函数在执行后都会自动返回一个promise对象
- await必须在async函数里使用,不能单独使用
- await后面需要跟promise对象,不然就没有意义,而且await后面的promise对象不必写then,因为await的作用之一就是获取后面promise对象成功状态传递出来的参数;
基础API:
- async函数返回一个promise对象
async function fn() {
return await 1
}
console.log(fn())
- async 要放到function关键字前面修饰,比如:async function f(){}
await不能脱离async独立使用,await一般要出现在async修饰的函数内 - async 函数内部的return返回值是作为promise对象的resolve参数存在的
async function fn() {
return await 1
}
fn().then(res => {
console.log(1)
}).catch(err => {
console.log(err)
})
-
await会让当前执行暂停,直到状态变成fulfilled或rejected;await等待的异步操作一般是promise await在等待什么?
- 一般我们都用await去等带一个async函数完成,不过按语法说明,await 等待的是一个表达式,这个表达式的计算结果是 Promise 对象或者其它值,所以,await后面实际可以接收普通函数调用或者直接量
- 如果await等到的不是一个promise对象,那跟着的表达式的运算结果就是它等到的东西; 如果是一个promise对象,await会阻塞后面的代码,等promise对象resolve,得到resolve的值作为await表达式的运算结果 虽然await阻塞了,但await在async中,async不会阻塞,它内部所有的阻塞都被封装在一个promise对象中异步执行
在async函数中使用await,那么await这里的代码就会变成同步的了,意思就是说只有等await后面的Promise执行完成得到结果才会继续下去,await就是等待,这样虽然避免了异步,但是它也会阻塞代码,所以使用的时候要考虑周全。
function fn() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 1000)
})
}
async function test() {
let p1 = await fn();
console.log(p1)
let p2 = await fn();
console.log(p2)
let p3 = await fn();
console.log(p3)
}
test()
对错误处理:
await可以直接获取到后面Promise成功状态传递的参数,但是却捕捉不到失败状态。在这里,我们通过给包裹await的async函数添加then/catch方法来解决,,async函数本身就会返回一个Promise对象。
//1)try....catch()...
function p1() {
return new Promise((resolve, reject) => {
setTimeout(function() {
reject({
"error": 400
})
}, 1000)
})
}
async function fn() {
try {
let res = await p1()
} catch (err) {
console.log(err)
}
}
fn()
//2)catch函数:
function p2() {
return new Promise((resolve, reject) => {
setTimeout(function() {
reject({
error: 400
})
// resolve("1")
}, 1000)
})
}
async function fn() {
let res = await p2().catch(err => {
console.log(err)
})
console.log(res)
}
fn()
并发处理
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("1")
}, 1000)
});
let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("2")
}, 2000)
});
async function fn(callback) {
let res1 = await p1;
let res2 = await p2;
callback([res1, res2])
}
fn((data) => {
console.log(data)
})
解决回调地狱
function timer(msg) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (msg == 2) reject("失败");
else resolve(msg);
}, 1000);
});
}
async function async_timer() {
let t1 = await timer(1);
console.log(t1);
let t2 = await timer(2).catch(err => {
console.log(err);
});
console.log(t2);
let t3 = await timer(3);
console.log(t3);
}
async_timer();