【异步编程】async、await

不念不忘少年蓝@ 2023-10-13 17:26 112阅读 0赞

什么是async和await

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

  1. async function test(){
  2. return 'hello world';
  3. }
  4. let result = test();
  5. console.log(result)

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

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

  1. async function test(){
  2. return 'hello world'
  3. }
  4. let result = test()
  5. console.log(result)
  6. result.then(v=>{
  7. console.log(v) // hello world
  8. })

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

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

await到底在等待什么?

  1. function getSomething() {
  2. return "something";
  3. }
  4. async function testAsync() {
  5. return Promise.resolve("hello async");
  6. }
  7. async function test() {
  8. const v1 = await getSomething();
  9. const v2 = await testAsync();
  10. console.log(v1, v2);
  11. }
  12. test();

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

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

  1. function testAsy(x){
  2. return new Promise(resolve=>{
  3. setTimeout(() => {
  4. resolve(x);
  5. }, 3000)
  6. }
  7. )
  8. }
  9. async function testAwt(){
  10. let result = await testAsy('hello world');
  11. console.log(result); // 3秒钟之后出现hello world
  12. console.log('cuger') // 3秒钟之后出现cug
  13. }
  14. testAwt();
  15. console.log('cug') //立即输出cug

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

aysnc、await的优点在哪

1. 错误处理

如果用promise

  1. const getJSON = () => {
  2. const jsonString = "{invalid JSON data}";
  3. return new Promise((resolve, reject) => {
  4. setTimeout(() => {
  5. resolve(jsonString);
  6. }, 1000);
  7. });
  8. };
  9. const makeRequest = () => {
  10. try {
  11. ddd;
  12. getJSON()
  13. .then((result) => {
  14. const data = JSON.parse(result);
  15. console.log(data);
  16. })
  17. .catch((err) => {
  18. console.log("第一个catch");
  19. console.log(err);
  20. });
  21. } catch (err) {
  22. console.log("第二个catch");
  23. console.log(err);
  24. }
  25. };
  26. makeRequest();

如果用await

  1. const makeRequest = async () => {
  2. try {
  3. // this parse may fail
  4. const data = JSON.parse(await getJSON())
  5. console.log(data)
  6. }
  7. catch (err) {
  8. console.log(err)
  9. }
  10. }

错误信息更加明确

  1. const getJSON = () => {
  2. const jsonString = "{invalid JSON data}";
  3. return new Promise((resolve, reject) => {
  4. setTimeout(() => {
  5. resolve(jsonString);
  6. }, 200);
  7. });
  8. };
  9. const getJSON2 = () => {
  10. const jsonString = "{invalid JSON data}";
  11. return new Promise((resolve, reject) => {
  12. setTimeout(() => {
  13. reject(jsonString);
  14. }, 200);
  15. });
  16. };
  17. const makeRequest = () => {
  18. return getJSON()
  19. .then(() => getJSON())
  20. .then(() => getJSON2())
  21. .then(() => getJSON())
  22. .then(() => getJSON())
  23. .then(() => getJSON());
  24. };
  25. makeRequest().catch((err) => {
  26. console.log("出现错误,进入catch");
  27. console.log(err);
  28. });

剩余的优势

https://blog.csdn.net/xufeiayang/article/details/80484116

发表评论

表情:
评论列表 (有 0 条评论,112人围观)

还没有评论,来说两句吧...

相关阅读

    相关 异步编程

    及面试题:并发与并行的区别? 异步和这小节的知识点其实并不是一个概念,但是这两个名词确实是很多人都常会混淆的知识点。其实混淆的原因可能只是两个名词在中文上的相似,在英文...

    相关 异步编程

      如果需要 I/O 绑定(例如从网络请求数据或访问数据库),则需要利用异步编程。     C\ 拥有语言级别的异步编程模型,它使你能轻松编写异步代码,而无需应付回叫...

    相关 异步编程-Future

    Future可以说是在Dart异步编程中随处可见,比如一个网络请求返回的是Future对象,或者访问一个SharedPreferences返回一个Future对象等等。异步操作

    相关 异步编程-Future

    Future可以说是在Dart异步编程中随处可见,比如一个网络请求返回的是Future对象,或者访问一个SharedPreferences返回一个Future对象等等。异步操作

    相关 JavaScript异步编程

    简介 JavaScript是一种单线程执行的脚本语言,为了不让一段JavaScript代码执行时间过久,阻塞UI的渲染或者是鼠标事件处理,通常会采用一种异步的[编程][Lin

    相关 java异步编程

        很多时候我们都希望能够最大的利用资源,比如在进行IO操作的时候尽可能的避免同步阻塞的等待,因为这会浪费CPU的资源。如果在有可读的数据的时候能够通知程序执行读操作甚至由

    相关 异步编程——promise

    异步编程——promise 定义 Promise是异步编程的一个解决方案,相比传统的解决方法——回调函数,使用Promise更为合理和强大,避免了回调函数之间的层层嵌套,...