js中async/await与Promise的区别

 更新时间:2024年04月09日 09:59:59   作者:接着奏乐接着舞。  
在JavaScript开发中,异步编程是一个无法避免的话题,本文主要介绍了js中async/await与Promise的区别,具有一定的参考价值,感兴趣的可以了解一下
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

基本概念

首先,我们需要明白async/await和Promise都是JavaScript中处理异步操作的API。

  • Promise: 是一种代表了某个异步操作最终完成(或失败)及其结果值的对象。
  • async/await: 是基于Promise的语法糖,它允许我们以更同步的方式编写异步代码。

使用Promise

基本语法
Promise.all() 接受一个 Promise 数组作为参数,返回一个新的 Promise 实例。这个新 Promise 的行为表现为:

  • 当所有传入的 Promises 都成功解决时,它会解决(resolve)为一个包含所有 Promises 结果的数组。
  • 如果任何一个 Promise 失败(即被拒绝),Promise.all() 返回的 Promise 会立即失败,并返回相应的错误。

在没有async/await之前,我们通常通过链式调用.then().catch()方法来处理Promise。例如,如果要按顺序执行两个异步操作,可能会这样写:

doSomethingAsync()
  .then(result => {
    console.log(result);
    return doSomethingElseAsync(result);
  })
  .then(newResult => {
    console.log(newResult);
  })
  .catch(error => {
    console.error('Something went wrong', error);
  });

这种方式可以有效地处理异步操作,但当涉及到多个异步操作时,代码可能会变得复杂和难以阅读,这通常被称为“回调地狱”。

并行 vs 串行

Promise.all() 的一个关键优势是它能够并行处理 Promises。这意味着所有 Promises 都是同时启动的,这与串行执行(一个接一个地执行)形成对比。并行执行可以显著提高程序的效率,特别是在处理多个独立任务时。

快速失败机制

Promise.all() 实现了快速失败机制,即如果其中一个 Promise 失败,则整个 Promise.all() 调用会立即失败。这种机制保证了一致的错误处理,但也意味着在某些场景下需要更谨慎地处理错误。

错误处理策略

由于快速失败的特性,使用 Promise.all() 时应该特别注意错误处理。例如,如果你正在从多个源加载重要数据,一个源的失败不应该阻碍其他数据的处理。这时,你可以在每个单独的 Promise 上使用 .catch() 方法来处理错误,确保每个 Promise 都不会抛出错误。

Promise.all([
  fetchUserInfo

(1).catch(err => ({ error: err.message })),
  fetchOrderHistory(1).catch(err => ({ error: err.message }))
])
.then(([userInfo, orders]) => {
  if (!userInfo.error) {
    console.log('用户信息:', userInfo);
  }
  if (!orders.error) {
    console.log('订单历史:', orders);
  }
})
.catch(error => {
  console.error('未预期的错误:', error);
});

在这个修改后的例子中,即使 fetchUserInfo 或 fetchOrderHistory 中的一个失败了,另一个的结果仍然会被处理。

实际应用场景

Promise.all() 的应用场景非常广泛,以下是一些具体的例子:

1. 资源加载

在网页开发中,你可能需要同时加载多个资源,如图片、JSON 数据和脚本文件。使用 Promise.all() 可以同时启动所有资源的加载,并在全部资源加载完成后执行后续操作。

let imageLoadPromise = loadImage('image.png');
let dataLoadPromise = fetchData('/data.json');
let scriptLoadPromise = loadScript('script.js');

Promise.all([imageLoadPromise, dataLoadPromise, scriptLoadPromise])
    .then(([image, data, script]) => {
        // 所有资源加载完成
    })
    .catch(error => {
        // 处理加载错误
    });

2. 数据库操作

在服务器端应用程序中,当你需要执行多个没有依赖的数据库查询时,Promise.all() 可以并行执行这些查询,提高查询效率。

let userQuery = db.query("SELECT * FROM users WHERE id = ?", [userId]);
let postsQuery = db.query("SELECT * FROM posts WHERE authorId = ?", [userId]);

Promise.all([userQuery, postsQuery])
    .then(([users, posts]) => {
        // 处理查询结果
    })
    .catch(error => {
        // 处理数据库错误
    });

3. API 聚合

在构建一个聚合多个 API 数据的服务时,Promise.all() 可以并行调用这些 API,并在所有调用都完成后聚合这些数据。

let weatherPromise = fetchWeather(cityId);
let newsPromise = fetchNews(topic);

Promise.all([weatherPromise, newsPromise])
    .then(([weather, news]) => {
        // 创建包含天气和新闻的聚合数据
    })
    .catch(error => {
        // 处理 API 调用错误
    });

使用async/await

async/await是在ES2017中引入的,使得异步代码的阅读和编写更像是传统的同步代码。async关键字用于声明一个异步函数,而await关键字则用于等待一个Promise的解决(fulfill)或拒绝(reject)。

同样的操作,使用async/await可以这样写:

async function asyncFunction() {
  try {
    const result = await doSomethingAsync();
    console.log(result);

    const newResult = await doSomethingElseAsync(result);
    console.log(newResult);
  } catch (error) {
    console.error('Something went wrong', error);
  }
}

在这个示例中,await使得JavaScript运行时等待Promise的解决,并且暂停函数的执行,直到Promise被解决。如果Promise被拒绝,错误将被catch块捕获。

总结区别

  • 语法清晰async/await提供了一种更清晰、更直观的方式来处理异步操作。代码看起来更像是同步的,因此更易于理解和维护。
  • 错误处理: 使用async/await时,可以使用传统的try/catch语句进行错误处理,这对于很多开发者来说更加熟悉。
  • 调试友好async/await使得在异步代码中使用断点调试变得更加直观。
  • 基于Promiseasync/await是建立在Promise之上的,实质上它并没有替代Promise的功能,而是提供了一种更简洁的使用方式。

需要注意的是,async/await并不是在所有情况下都替代Promise链。例如,在处理多个并行异步操作时,Promise.all()仍然是一个非常有用的选择。

到此这篇关于js中async/await与Promise的区别的文章就介绍到这了,更多相关js async/await与Promise内容请搜索程序员之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持程序员之家!

相关文章

  • BootStrap 动态表单效果

    BootStrap 动态表单效果

    这篇文章主要介绍了BootStrap 动态表单效果,实现代码分为js部分和html部分,代码简单易懂,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-06-06
  • js中日期的加减法

    js中日期的加减法

    JavaScript实现日期加减计算功能代码实例,因为在js中没有类似C#中的AddDays方法,所以要想实现日期加减的话,就需要自己写函数来实现。
    2015-05-05
  • JavaScript基于原型链的继承

    JavaScript基于原型链的继承

    原型链是JavaScript中继承的主要方法。本文重点给大家介绍JavaScript基于原型链的继承,非常不错,具有参考借鉴价值,感兴趣的朋友一起学习吧
    2016-06-06
  • javascript将16进制的字符串转换为10进制整数hex

    javascript将16进制的字符串转换为10进制整数hex

    这篇文章主要介绍了javascript将16进制的字符串转换为10进制整数hex,需要的朋友可以参考下
    2020-03-03
  • Js如何判断客户端是PC还是手持设备简单分析

    Js如何判断客户端是PC还是手持设备简单分析

    在工作过程中,许多朋友会经常用到js判断客户端是PC还是手持设备,今天将提供以下方法,需要的朋友可以参考下
    2012-11-11
  • 微信小程序实现form表单本地储存数据

    微信小程序实现form表单本地储存数据

    这篇文章主要为大家详细介绍了微信小程序实现form表单本地储存数据,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-06-06
  • js判断文本框剩余可输入字数的方法

    js判断文本框剩余可输入字数的方法

    这篇文章主要介绍了js判断文本框剩余可输入字数的方法,可实现直观显示文本框可输入字数的功能,非常具有实用价值,需要的朋友可以参考下
    2015-02-02
  • js中let和var定义变量的区别

    js中let和var定义变量的区别

    这篇文章主要介绍了js中let和var定义变量的区别,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2018-02-02
  • Javascript 中创建自定义对象的方法汇总

    Javascript 中创建自定义对象的方法汇总

    这篇文章主要汇总介绍了Javascript 中创建自定义对象的方法,需要的朋友可以参考下
    2014-12-12
  • js中parseInt()诡异行为的探究与改正

    js中parseInt()诡异行为的探究与改正

    这篇文章主要给大家介绍了关于js中parseInt()诡异行为的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04

最新评论


http://www.vxiaotou.com