针对异步编程,我们学习过Ajax的回调形式,Promise的链式调用形式
$.ajax({
url,
data,
success:function (result){
$.ajax({
data:result,
success:function(result1){
$.ajax({
url,
data:result1
})
}
})
}
})
嵌套调用,会出现回调地狱,可读性不强
为了解决这个问题,Promise应用而生
// 链式调用 没有嵌套
axios({ url, data}).then(result => {
return axios({ data:result })
}).then(result1 => {
return axios({ data:result1 })
}).then(result2 => {
return axios({ data: result2 })
}).then(result3 => {
return axios({ data: result3 })
})
多个请求之间存在依赖关系,使用Promise的链式调用的话,那么有几个请求就需要写几个then,比较麻烦
async function test() {
let result1 = await axios({url,data});
let result2 = await axios({data:result1});
let result3 = await axios({data:result2});
console.log(result3);
}
代码简单,逻辑清晰,可读性强
async和Promise都是异步方法,区别是async生成的结果是Promise对象,async是Promise的终结版。
Async/Await是ES7引入的新的语法,可以更加方便的进行异步操作
① async关键字用于函数上, await只能用在async函数里面,不能单独使用
async function text(id) {
const res = await axios.get("/data");
return rets;
}
② async返回的是一个Promise对象,await会等待Promise完成之后直接返回最终的结果
async function test() {}
console.log(test()); // 打出 Promise { undefined }
③ await 等待的是一个Promise对象,后面必须跟一个Promise对象,但是不必写then(),Await可以直接得到异步的结果
async function test() {
let result = await new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
},1000)
})
console.log(result)
}
test()
async function queryData(id) {
const info = await axios.get("/data");
const res = await axios.get("async2?info=" + info.data);
return res;
}
queryData.then((res) => {
console.log(res);
});
这样使用会打破这个两个fetch()操作的并行,因为这样写会等到第一个fetch执行完之后再执行第二次fetch
async function test(){
const a = await fetch ('http://abc.com/1');
const b = await fetch ('http://abc.com/2');
}
更高效的做法是使用Promise.all()
组合起来,然后再去await
async function test(){
const promiseA = fetch ('http://abc.com/1');
const promiseB = fetch ('http://abc.com/2');
const[a,b] = await Promise.all([promiseA ,promiseB])
}
修改后代码运行效率提高一倍
尽管在回调函数中写了await,但这里的forEach会立刻返回,它并不会暂停等到所有异步操作都执行完毕
async function test(){
[1,2,3].forEach(async (i) => {
await Request()
});
console.log('done');
}
test()
如果希望等到循环中的异步操作都一一完成之后才继续执行,那么我们应当使用传统的for循环
async function test(){
for(let i of [1,2,3]){
await request()
}
console.log('done');
}
test()
如果想要循环中的所有操作并发执行,可以使用for await
这里的for循环一会会等到所有的异步操作都完成之后才继续向后执行
async function test(){
const promises = [
request(),
request(),
request(),
];
for await (let result of promises) {
// ...
}
console.log('done');
}
test()
await只能被用在异步函数(async function)中,如果想要在最外层使用await,那么需要先定义一个异步函数,然后在函数体重使用它
// 方法一
async function test() {
await request();
}
test();
// 方法二
(async () => {
await request();
})();
async function test() {
console.log(1);
let result = await Promise.resolve("success");
console.log(2);
return result;
}
test()
.then((result) => {
console.log(3);
})
.catch((error) => {
console.log(3);
});
console.log(4);
输出结果: 1,4,2,3