服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服务器之家 - 编程语言 - JavaScript - js教程 - 有了这五个方法,轻松处理异步任务

有了这五个方法,轻松处理异步任务

2024-03-07 14:12全栈修仙之路 js教程

本文我将介绍 Promise 对象上 5 个非常有用的方法,掌握这些方法之后,可以让你更好地解决工作遇到的一些异步问题。

有了这五个方法,轻松处理异步任务

在 JavaScript 中,许多操作都是异步的,比如发起网络请求、读取文件、定时器等。Promise 提供了一种更加结构化和易于理解的方式来处理异步操作,使得异步代码更加清晰易读,避免了回调地狱的问题。

本文我将介绍 Promise 对象上 5 个非常有用的方法,掌握这些方法之后,可以让你更好地解决工作遇到的一些异步问题。

Promise.all()

当你需要并行执行多个异步操作,并且只有当所有异步操作都成功完成时才继续执行后续代码。

const promise1 = Promise.resolve("Promise");
const promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 2000, "is");
});
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 1000, "useful");
});

Promise.all([promise1, promise2, promise3]).then((values) => {
  console.log(values);
});

以上代码成功运行后,控制台会输出以下结果:

[ 'Promise', 'is', 'useful' ]

但如果某个 promise 对象在执行过程中抛出异常,比如,promise2 对象在执行时抛出异常:

const promise2 = new Promise((resolve, reject) => {
  setTimeout(reject, 2000, new Error("Crash..."));
});

那么,你就无法正常获取 promise1 和 promise3 对象返回的结果。针对这个问题,你可以使用 Promise.allSettled() 方法。

Promise.allSettled()

当你想要等待多个异步操作完成,并且你需要知道每个异步操作的结果。

const promise1 = Promise.resolve("Promise");
const promise2 = new Promise((resolve, reject) => {
  setTimeout(reject, 2000, new Error("Crash..."));
});
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 1000, "useful");
});

Promise.allSettled([promise1, promise2, promise3]).then((values) => {
  console.log(values);
});

运行以上代码之后,控制台会输出以下结果。数组中每个对象上的 status 属性是用于标识对应 promise 对象的执行状态。

[
  { status: 'fulfilled', value: 'Promise' },
  {
    status: 'rejected',
    reason: Error: Crash...
  },
  { status: 'fulfilled', value: 'useful' }
]

Promise.race()

当你有多个异步操作,并且你只关心哪个操作最先完成,不管它是成功还是失败。

const promise1 = new Promise((resolve, reject) => {
  setTimeout(reject, 1000, "Promise 1 resolved");
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 2000, "Promise 2 resolved");
});

Promise.race([promise1, promise2]).then((value) => {
  console.log(value);
});

以上代码成功运行后,控制台会输出 "Promise 1 resolved"。

Promise.any()

当你有多个异步操作,并且你想要得到第一个成功的异步操作的结果,而忽略其他已失败的异步操作。

const promise1 = Promise.reject("any");
const promise2 = new Promise((resolve) =>
  setTimeout(resolve, 100, "Promise 2 resolved")
);
const promise3 = new Promise((resolve) =>
  setTimeout(resolve, 500, "Promise 3 resolved")
);

Promise.any([promise1, promise2, promise3]).then((value) => {
  console.log(value);
});

以上代码成功运行后,控制台会输出 "Promise 2 resolved"。

Promise.withResolvers()

在某些场景下,我们希望在外部控制 Promise 对象的状态。比如,在请求网络数据的场景,当成功接收所有数据后,才调用 resolve 方法设置当前 Promise 的返回数据。

let resolve, reject;
const promise = new Promise((res, rej) => {
  resolve = res;
  reject = rej;
});

asyncRequest(config, response => {
  const buffer = [];
  response.on('callback-request', id => {
    promise.then(data => callback(id, data));
  });
  response.on('data', data => buffer.push(data));
  response.on('end', () => resolve(buffer));
  response.on('error', reason => reject(reason));
});

上述的场景在日常工作中很常见,为了避免重复写以下代码。

let resolve, reject;
const promise = new Promise((res, rej) => {
  resolve = res;
  reject = rej;
});

ts39 增加了 proposal-promise-with-resolvers 草案,目前该草案的状态已经是 Stage 4。不过在使用的过程中,需要注意它的兼容性:

有了这五个方法,轻松处理异步任务

对于不支持 Promise.withResolvers() 方法的环境,我们可以通过通过自定义函数来实现对应的功能。比如,TypeScript 源码中,定义了一个 defer 函数来实现 Promise.withResolvers()  方法同样的功能。

export function defer<T = void>(): Deferred<T> {
    let resolve!: (value: T | PromiseLike<T>) => void;
    let reject!: (reason: unknown) => void;
    const promise = new Promise<T>((_resolve, _reject) => {
        resolve = _resolve;
        reject = _reject;
    });
    return { resolve, reject, promise };
}

原文地址:https://mp.weixin.qq.com/s/gri-8ClxnLZGFBpOA6FoLw

延伸 · 阅读

精彩推荐
  • js教程JavaScript深拷贝方法structuredClone使用

    JavaScript深拷贝方法structuredClone使用

    这篇文章主要为大家介绍了JavaScript深拷贝方法structuredClone使用示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪...

    天行无忌6102023-06-12
  • js教程一篇带你快速上手 Esbuild

    一篇带你快速上手 Esbuild

    为什么 Vite 那么快呢?除了使用了 ES modules 之外,Vite 内部还使用了一个神器— esbuild。...

    全栈修仙之路6552022-02-24
  • js教程Intersection Observer交叉观察器示例解析

    Intersection Observer交叉观察器示例解析

    这篇文章主要为大家介绍了Intersection Observer交叉观察器示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪...

    完锤子7322023-05-23
  • js教程微信小程序自定义胶囊样式

    微信小程序自定义胶囊样式

    这篇文章主要为大家详细介绍了微信小程序自定义胶囊样式,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    四曦11552021-12-21
  • js教程fabric.js实现diy明信片功能

    fabric.js实现diy明信片功能

    这篇文章主要为大家详细介绍了fabric.js实现diy明信片功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    C49111408810412022-02-19
  • js教程微信小程序实现购物车小功能

    微信小程序实现购物车小功能

    这篇文章主要为大家详细介绍了微信小程序实现购物车小功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    小王同学Max5862021-12-22
  • js教程用 JavaScript 实现一个简单的笔记应用程序

    用 JavaScript 实现一个简单的笔记应用程序

    记笔记是学习新知识技能比较好的做法。记笔记的一些好处是:记笔记可以作为学习辅助工具,记笔记可以提高注意力和对细节的关注,促进主动学习,并...

    web前端开发8002022-10-24
  • js教程微信小程序弹窗禁止页面滚动的实现代码

    微信小程序弹窗禁止页面滚动的实现代码

    这篇文章主要介绍了微信小程序弹窗禁止页面滚动的实现代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需...

    任我行RQ5662021-12-23