【异步编程】async、await

什么是async和await

async 用于声明一个异步函数,await 用于等待一个异步方法执行完成。当然语法上强制规定await只能出现在asnyc函数中,先来看看async函数返回了什么。

async function test(){
   return 'hello world';
}
let result = test(); 
console.log(result)

通过执行结果我们可以发现,async 函数返回的是一个 Promise 对象。你可能会有疑问,在上例中,我们明明返回的是一个字符串“hello word”,并不是返回的 Promise 对象,为什么打印出来的结果是 Promise 对象呢?那是因为,如果在函数中 return 一个基本类型,async 会把这个直接量通过 Promise.resolve() 封装成 Promise 对象。

由于 async 函数返回的是一个 Promise 对象,所以在最外层不能用 await 获取其返回值的情况下,当然应该用原来的方式:then() 链来处理这个 Promise 对象,就像这样:

async function test(){
   return 'hello world'
}
let result = test() 
console.log(result)
result.then(v=>{
    console.log(v)   // hello world
})

那如果 async 函数没有返回值,又该如何?很容易想到,它会返回 Promise.resolve(undefined)。
联想一下 Promise 的特点——无等待,所以在没有 await 的情况下执行 async 函数,它会立即执行,返回一个 Promise 对象,并且,绝不会阻塞后面的语句。这和普通返回 Promise 对象的函数并无二致。

注意:Promise.resolve(x) 可以看作是 new Promise(resolve => resolve(x)) 的简写,可以用于快速封装字面量对象或其他对象,将其封装成 Promise 实例。

await到底在等待什么?

function getSomething() {
    return "something";
}
async function testAsync() {
    return Promise.resolve("hello async");
}
async function test() {
    const v1 = await getSomething();
    const v2 = await testAsync();
    console.log(v1, v2);
}
test();

await 表达式的运算结果取决于它等的是什么。

如果它等到的不是一个 Promise 对象,那 await 表达式的运算结果就是它等到的东西。
如果它等到的是一个 Promise 对象,await 就忙起来了,它会阻塞后面的代码,等着 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。

function testAsy(x){
   return new Promise(resolve=>{setTimeout(() => {
       resolve(x);
     }, 3000)
    }
   )
}
async function testAwt(){    
  let result =  await testAsy('hello world');
  console.log(result);    // 3秒钟之后出现hello world
  console.log('cuger')   // 3秒钟之后出现cug
}
testAwt();
console.log('cug')  //立即输出cug

这就是 await 必须用在 async 函数中的原因。async 函数调用不会造成阻塞,它内部所有的阻塞都被封装在一个 Promise 对象中异步执行。await暂停当前async的执行,所以’cug’'最先输出,hello world’和‘cuger’是3秒钟后同时出现的。

aysnc、await的优点在哪

1. 错误处理

如果用promise

    const getJSON = () => {
      const jsonString = "{invalid JSON data}";

      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(jsonString);
        }, 1000);
      });
    };

    const makeRequest = () => {
      try {
        ddd;
        getJSON()
          .then((result) => {
            const data = JSON.parse(result);
            console.log(data);
          })
          .catch((err) => {
            console.log("第一个catch");
            console.log(err);
          });
      } catch (err) {
        console.log("第二个catch");
        console.log(err);
      }
    };

    makeRequest();

如果用await

 const makeRequest = async () => {
      try {
          // this parse may fail
          const data = JSON.parse(await getJSON())
          console.log(data)
      } 
      catch (err) {
          console.log(err)
      }
   }

错误信息更加明确

 const getJSON = () => {
      const jsonString = "{invalid JSON data}";

      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(jsonString);
        }, 200);
      });
    };

    const getJSON2 = () => {
      const jsonString = "{invalid JSON data}";

      return new Promise((resolve, reject) => {
        setTimeout(() => {
          reject(jsonString);
        }, 200);
      });
    };

    const makeRequest = () => {
      return getJSON()
        .then(() => getJSON())
        .then(() => getJSON2())
        .then(() => getJSON())
        .then(() => getJSON())
        .then(() => getJSON());
    };

    makeRequest().catch((err) => {
      console.log("出现错误,进入catch");
      console.log(err);
    });

剩余的优势

https://blog.youkuaiyun.com/xufeiayang/article/details/80484116

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

codereasy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值