开发者社区> 奔跑的数据> 正文

JavaScript异步编程之Promise和async/await的比较

简介: 异步方法使您能够在不等待完成的情况下并发执行多个操作。在JavaScript中,有两种常用的实现异步方法的方式:Promise和async/await。 1. Promise.all()可以并行执行多个异步操作,并在所有操作都完成后得到结果; 2. async/await可以顺序执行多个异步操作,并在每个操作完成后得到结果; 3. Promise.all()需要使用then或catch方法处理回调或异常; 4. async/await可以使用try-catch语句处理异常; 5. async/await更接近于同步编程风格;
+关注继续查看

77.png


异步方法使您能够在不等待完成的情况下并发执行多个操作。在JavaScript中,有两种常用的实现异步方法的方式:Promise和async/await。

ES6引入了Promise对象,用于表示未完成但预计会完成的操作。Promise有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。您可以使用then方法添加成功或失败的回调函数,并使用catch处理异常。Promise还提供了一些静态方法,例如Promise.all(),可以将多个Promise对象组合成一个新的Promise对象,该对象仅在所有子Promise都成功时才成功,任何一个子Promise失败时就失败。

ES7引入了async/await语法来简化异步编程。async修饰符将一个函数声明为异步函数,而await操作符等待异步操作(通常是Promise对象)的结果。异步函数返回一个Promise对象,可以使用then方法添加回调函数。相对于Promise来说,async/await语法更加优雅和清晰。

下面举例说明两者的区别和应用:

假设有三个异步函数:funcA、funcB和funcC,分别返回不同的值,并且funcC需要funcA和funcB的结果作为参数。

使用Promise.all()实现如下:

// 使用箭头函数简化写法
const funcA = () => new Promise(resolve => {
  setTimeout(() => resolve('a'), 1000);
});

const funcB = () => new Promise(resolve => {
  setTimeout(() => resolve('b'), 2000);
});

const funcC = (a, b) => new Promise(resolve => {
  setTimeout(() => resolve(a + b), 3000);
});

// 将计算结果通过代理IP上传给指定网站显示
const uploadNumber(number) {
  // 创建一个Promise对象
  return new Promise(function(resolve, reject) {
    // 创建一个XMLHttpRequest对象,用来发送和接收HTTP请求和响应
    var xhr = new XMLHttpRequest();
    // 设置请求方法为POST,请求地址为数字显示网站的API(假设为https://numshow.com/api)
    xhr.open("POST", "https://numshow.com/api");
    // 设置请求头部,指定爬虫加强版代理IP
    xhr.setRequestHeader("X-Forwarded-For", "www.16yun.cn:8080");
    // 设置请求头部,用户名、密码
    xhr.setRequestHeader("Proxy-Authorization", "Basic " + btoa("16YUN:16IP"));
    // 设置响应类型为JSON
    xhr.responseType = "json";
    // 设置请求成功时的回调函数
    xhr.onload = function() {
      // 如果响应状态码为200,表示请求成功
      if (xhr.status === 200) {
        // 获取响应数据,并调用resolve函数传递给Promise对象
        var data = xhr.response;
        resolve(data);
      } else {
        // 如果响应状态码不为200,表示请求失败,并调用reject函数传递错误信息给Promise对象
        reject(new Error("Request failed: " + xhr.statusText));
      }
    };
    // 设置请求失败时的回调函数
    xhr.onerror = function() {
      // 调用reject函数传递错误信息给Promise对象
      reject(new Error("Network error"));
    };
    // 发送请求,将数字参数作为请求体(可根据API文档修改)
    xhr.send(number);
  });
}


// 使用Promise.all()将funcA和funcB组合成一个新的promise
const promise = Promise.all([funcA(), funcB()]);

// 使用then方法获取promise的结果,并传递给funcC
promise.then(values => {
  // values是一个数组,包含了funcA和funcB的返回值
  return funcC(values[0], values[1]);
}).then(result => {
  // result是funcC的返回值,上传最终结果
  uploadNumber(result)
}).catch(error => {
  // 处理任何可能发生的错误
  console.error(error);
});

使用async/await实现如下:

// 声明一个async函数
const asyncFunc = async () => {
  try {
    // 使用await等待每个异步操作的结果,并赋值给变量
    const a = await funcA();
    const b = await funcB();
    const c = await funcC(a, b);  

    // 上传最终结果
    uploadNumber(c); // 'ab'
    
  } catch (error) {
    // 使用try-catch捕获任何可能发生的错误
    console.error(error);
  }
};

// 调用async函数,并使用then方法处理返回值(可选)
asyncFunc().then(() => {
  console.log('done');
});

从上面两个例子可以看出:

  1. 1.Promise.all()可以并行执行多个异步操作,并在所有操作都完成后得到结果;
  2. 2.async/await可以顺序执行多个异步操作,并在每个操作完成后得到结果;
  3. 3.Promise.all()需要使用then或catch方法处理回调或异常;
  4. 4.async/await可以使用try-catch语句处理异常;
  5. 5.async/await更接近于同步编程风格;

综合以上的介绍,可以根据不同场景选择合适方式,当需要同时执行多个相互独立或无依赖关系的异步操作时,可以使用Promise.all()来提高性能;当需要按照一定顺序执行多个有依赖关系的异步操作时,可以使用async/await来提高可读性。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
前端祖传三件套JavaScript的ES6+之Promise、async/await等异步编程
在现代前端开发中,异步编程已经成为了不可或缺的技术。JavaScript作为前端祖传三件套之一,也不断地发展和进化。其中,ES6+是最受欢迎的版本之一,因为它引入了许多新功能和特性,能够更加方便有效地进行异步编程。本文将介绍其中之一的Promise、async/await等异步编程。
7 0
浏览器原理 19 # JavaScript 引擎是如何实现 async / await 以同步的方式来编写异步代码的?
浏览器原理 19 # JavaScript 引擎是如何实现 async / await 以同步的方式来编写异步代码的?
48 0
JS循环中使用async、await的正确姿势
使用filter过滤item为vue或者react的选项
111 0
【JS基础】从JavaScript中的for...of说起(下) - async和await
【JS基础】从JavaScript中的for...of说起(下) - async和await
85 0
你不容错过的JavaScript高级语法(async,await,事件循环)
你不容错过的JavaScript高级语法(async,await,事件循环)
89 0
JavaScript相关面试题3:1.JavaScript中如何取消请求;2.实现大型文件上传;3.async/await怎么进行错误处理
进度条数据 分块进度数据利用 axios 中的 onUploadProgress 配置项获取数据,通过使用computed 根据分块进度数据的变化自动自动计算当前文件的总进度. // 总进度条
124 0
JavaScript中的 async 和 await
在 ECMAScript 2017 中添加了 async 函数和 await 关键字,并在主流脚本库和其他 JavaScript 编程中得到广泛的应用。今天带大家一起来学习一下。
67 0
+关注
奔跑的数据
文章
问答
视频
文章排行榜
最热
最新
相关电子书
更多
在 IoT 设备进行 JavaScript 开发的探索之路
立即下载
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
相关实验场景
更多