javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > js async/await与Promise

js中async/await与Promise的区别

作者:接着奏乐接着舞。

在JavaScript开发中,异步编程是一个无法避免的话题,本文主要介绍了js中async/await与Promise的区别,具有一定的参考价值,感兴趣的可以了解一下

基本概念

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

使用Promise

基本语法
Promise.all() 接受一个 Promise 数组作为参数,返回一个新的 Promise 实例。这个新 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并不是在所有情况下都替代Promise链。例如,在处理多个并行异步操作时,Promise.all()仍然是一个非常有用的选择。

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

您可能感兴趣的文章:
阅读全文