专栏名称: React
互联网从业者,专注于 React系列精彩内容推荐。关注大前端、Node技术全栈、Flutter、WebAssembly、鸿蒙(harmonyOS)、小程序等互联网科技领域最前沿技术,定期分享个人创业经验。
目录
相关文章推荐
新声Pro  ·  我们与鬼神的距离 ·  18 小时前  
新声Pro  ·  我们与鬼神的距离 ·  18 小时前  
秦皇岛晚报  ·  【中国好手艺117】铁艺灯笼 ·  3 天前  
秦皇岛晚报  ·  【中国好手艺117】铁艺灯笼 ·  3 天前  
古典文献学微刊  ·  编辑·手记 | ... ·  5 天前  
51好读  ›  专栏  ›  React

都说 Promise 新增这个API提效300%,就是不说怎么用?我教你

React  · 公众号  ·  · 2024-07-19 23:12

主要观点总结

文章介绍了JavaScript中新的Promise API——Promise.withResolvers的功能和优势,以及如何在项目中配置使用。该API通过返回一对函数来直接解决或拒绝Promise,提高了代码的灵活性和模块化。文章还涉及到了兼容性问题和如何在现有项目中使用该特性的步骤。

关键观点总结

关键观点1: Promise.withResolvers的功能和优势

介绍Promise.withResolvers作为一个新的Promise API,通过返回包含Promise和两个函数(resolve和reject)的对象,为处理异步操作提供了更加灵活的工具。该API提高了代码的灵活性和模块化,使开发者能够更高效地编写和维护代码。

关键观点2: Promise.withResolvers的基础使用

通过模拟一个异步的网络请求的例子,展示了在使用Promise.withResolvers前后代码的差异,强调了该API在减少模板代码和使逻辑更加清晰方面的优势。

关键观点3: 兼容性注意点

指出Promise.withResolvers目前还处于Stage 3阶段,需要注意兼容性和支持度问题。提到主流浏览器尚未全面支持该特性,开发者需要考虑降级方案或使用Polyfill来保证代码的兼容性。

关键观点4: 如何在现有项目中使用Promise.withResolvers

详细介绍了如何在现有项目中配置Babel和webpack来使用Promise.withResolvers,包括安装必要的包、配置Babel和webpack的步骤,以及使用Promise.withResolvers的示例。


正文

击上方 React,关注公众号

回复加群,加入技术交流群交流

JavaScript 中, Promise 是处理异步操作的基础工具,它通过链式调用简化了代码结构。最近,一个新的 Promise API—— Promise.withResolvers 即将到来,它通过返回一对函数来直接解决或拒绝 Promise ,提高了代码的灵活性和模块化。

这个API目前处于 ECMAScript 提案的后期阶段,预示着它很快将被正式纳入标准。 Promise.withResolvers 的加入将进一步丰富 JavaScript 处理异步任务的能力,使开发者能够更高效地编写和维护代码。

Promise.withResolvers API 介绍

Promise.withResolvers 是一个静态方法,它的引入为处理异步操作提供了一个更加灵活的工具。该方法返回一个包含新的 Promise 对象和两个函数( resolve reject )的对象。这两个函数分别对应于传统 Promise 构造函数执行器( executor function )的两个参数。与传统 Promise 构造函数相比, withResolvers 方法的优势在于解决( resolve )和拒绝( reject )函数与 Promise 对象本身处于同一作用域,使得在复杂的异步处理场景下更加方便和灵活。

cosnt {promise, resolve, reject} = Promise.withResolvers() 完全等同于以下代码:

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

Promise.withResolvers API 基础使用

Promise.withResolvers 方法出现之前我们用 Promise 处理复杂业务逻辑时,以网络请求为例子,模拟一个异步的网络请求,并根据请求的结果执行相应的业务逻辑:

未使用 Promise.withResolvers() 之前

function getUserInfo(userId{
    return new Promise((resolve, reject) => {
        fetch(`https://api.****/users/${userId}`)
            .then(response => {
                if (response.ok) {
                    return response.json();
                } else {
                    throw new Error('Failed to fetch user info');
                }
            })
            .then(data => resolve(data))
            .catch(error => reject(error));
    });
}

getUserInfo(1)
    .then(userInfo => {
        console.log('User info:', userInfo);
        // 更新 UI 或进一步处理 userInfo
    })
    .catch(error => {
        console.error('An error occurred:', error);
        // 处理错误,比如显示错误消息
    });

使用 Promise.withResolvers 后,我们可以更优雅地实现相同的功能,减少了一些模板代码,并且使逻辑更加清晰:

function getUserInfo(userId{
    const { promise, resolve, reject } = Promise.withResolvers();

    fetch(`https://api.******/users/${userId}`)
        .then(response => {
            if (response.ok) {
                return response.json();
            } else {
                throw new Error('Failed to fetch user info');
            }
        })
        .then(data => resolve(data))
        .catch(error => reject(error));

    return promise;
}

getUserInfo(1)
    .then(userInfo => {
        console.log('User info:', userInfo);
        // 更新 UI 或进一步处理 userInfo
    })
    .catch(error => {
        console.error('An error occurred:', error);
        // 处理错误,比如显示错误消息
    });

在这个例子中,我们直接使用 Promise.withResolvers 来创建 Promise 和它的解决(resolve)与拒绝(reject)函数。这样一来,我们不再需要在 new Promise 的构造函数中手动包装 fetch 调用,而是可以直接在 fetch 的异步操作中调用 resolve reject 。这种方式不仅减少了代码的嵌套层次,也使得异步逻辑的控制更加直观和灵活。

兼容性注意点

虽然 Promise.withResolvers 提供了很大的便利性,但由于它目前还处于 Stage 3 阶段,其兼容性和支持度成为开发者需要注意的问题。预计到 2024 年,这一特性将正式成为 ECMAScript 标准的一部分。然而,在此之前,开发者需要注意:

  • 目前主流浏览器尚未全面支持这一特性,例如,谷歌浏览器需要 117 以上的版本才能使用。
image.png
  • 对于不支持该特性的环境,开发者需要考虑降级方案或者使用 Polyfill 来保证代码的兼容性。

如何在现有项目中使用

因为目前core-js中已经提供了对应的 polyfill

以目前手中的 Vue/React 为例

为了确保它能够在不支持该特性的浏览器中运行,你需要通过 Babel core-js polyfill 来实现。这里主要通过配置 Babel 来自动引入所需的 polyfill 。由于 Promise.any 是一个已经进入到 ECMAScript 标准的特性, core-js 包含了对它的支持,因此你可以直接利用 core-js polyfill 这个特性。以下是如何配置你的项目来使用 Promise.any 的步骤:

步骤 1: 安装必要的包

确保你的项目中已经安装了 @babel/core , @babel/preset-env , babel-loader , 和 core-js 。如果尚未安装,可以通过以下命令安装它们:

npm install --save core-js
npm install --save-dev @babel/core @babel/preset-env babel-loader

步骤 2: 配置 Babel

在你的项目根目录下,创建或更新 babel.config.js 文件,以包含对 core-js 的引用。这里是一个配置示例:

module.exports = {
  presets: [
    [
      '@babel/preset-env',
      {
        useBuiltIns'usage',
        corejs3// 指定使用 core-js 的版本
        // 根据项目需要配置目标环境
        targets"> 0.25%, not dead",
      },
    ],
  ],
};

这个配置告诉 Babel,根据你的代码实际使用情况( useBuiltIns: 'usage' )和目标环境,自动引入所需的 core-js polyfills 。这意味着,如果你的代码中使用了 Promise.withResolvers ,相应的 polyfill 将被自动引入,无需手动导入。

步骤 3: 配置 Webpack

确保你的 webpack 配置中已经设置了 babel-loader 来处理 JavaScript 文件。这通常在 webpack.config.js 文件的 module.rules 部分进行配置:

module: {
  rules: [
    {
      test/\.js$/,
      exclude/node_modules/,
      use: {
        loader'babel-loader',
        options: {
          presets: ['@babel/preset-env']
        }
      }
    },
    // 其他 loaders...
  ]
}

步骤 4: 使用 Promise.withResolvers







请到「今天看啥」查看全文