当前位置: 首页 > 工具软件 > Async Server > 使用案例 >

async与await是什么?async和await基本用法

宓弘壮
2023-12-01

一、为什么要使用async和await

针对异步编程,我们学习过Ajax的回调形式,Promise的链式调用形式

1、ajax回调模式

$.ajax({
    url,
    data,
    success:function (result){
        $.ajax({
            data:result,
            success:function(result1){
                $.ajax({
                    url,
                    data:result1
                })
            }
        })
    }
})

缺点

嵌套调用,会出现回调地狱,可读性不强
为了解决这个问题,Promise应用而生

2、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,比较麻烦

3、Async 和 Await

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

1、定义

Async/Await是ES7引入的新的语法,可以更加方便的进行异步操作

2、基本用法

① 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()

3、async/await处理多个异步请求

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);
});

三、await陷阱

1、连续await会打破代码并行

这样使用会打破这个两个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])
}

修改后代码运行效率提高一倍

2、在循环中执行异步操作,不能直接调用forEach()或者map()这一类方法

尽管在回调函数中写了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()

3、不能在全局或者普通函数中直接使用await关键字

await只能被用在异步函数(async function)中,如果想要在最外层使用await,那么需要先定义一个异步函数,然后在函数体重使用它

// 方法一
async function test() {
  await request();
}
test();

// 方法二
(async () => {
  await request();
})();

四、Async/Await小案例

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

 类似资料: