For AI agents: the complete documentation index is available at /tc39-atlas/llms.txt, the full documentation bundle is available at /tc39-atlas/llms-full.txt, and this page is available as Markdown at /tc39-atlas/proposals/stage/4/proposal-promise-with-resolvers.md.
  • 简体中文
  • Promise.withResolvers S4

    提案概览
    提案速览

    该提案解决了手动创建 Promise 时提取 resolve 和 reject 函数所需的样板代码问题。它添加了一个静态方法 Promise.withResolvers(),返回包含 promise 及其 resolve/reject 函数的对象。

    Note

    以下 README 来自上游仓库,其中的阶段或状态标注可能滞后;当前信息以提案概览为准。

    Promise.withResolvers

    注意:该提案现处于第 4 阶段。查看规范 PR:https://github.com/tc39/ecma262/pull/3179

    状态

    阶段:4

    提案者:

    作者:

    第 3 阶段幻灯片 第 2 阶段幻灯片 第 1 阶段幻灯片

    概述

    当手动创建一个 Promise 时,用户必须传入一个执行器回调,该回调接受两个参数:一个 resolve 函数,用于触发 Promise 的解决;一个 reject 函数,用于触发拒绝。如果回调中嵌入了对异步函数的调用,并且该函数最终会触发解决或拒绝(例如注册事件监听器),这种方法效果很好。

    const promise = new Promise((resolve, reject) => {
      asyncRequest(config, response => {
        const buffer = [];
        response.on('data', data => buffer.push(data));
        response.on('end', () => resolve(buffer));
        response.on('error', reason => reject(reason));
      });
    });

    然而,开发人员经常希望在实例化 Promise 之后配置其解决和拒绝行为。目前,这需要一个繁琐的变通方法来从回调作用域中提取 resolve 和 reject 函数:

    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));
    });

    开发人员可能还有要求将 resolve/reject 传递给多个调用方,因此他们必须以这种方式实现:

    let resolve = () => { };
    let reject = () => { };
    
    function request(type, message) {
      if (socket) {
        const promise = new Promise((res, rej) => {
          resolve = res;
          reject = rej;
        });
        socket.emit(type, message);
        return promise;
      }
    
      return Promise.reject(new Error('Socket unavailable'));
    }
    
    socket.on('response', response => {
      if (response.status === 200) {
        resolve(response);
      }
      else {
        reject(new Error(response));
      }
    });
    
    socket.on('error', err => {
      reject(err);
    });

    这是开发人员经常重写的样板代码。本提案旨在向 Promise 构造函数添加一个静态方法,暂定名为 withResolvers,它返回一个 Promise 及其便于使用的解决和拒绝函数。

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

    此方法或类似方法可能被部分委员会成员称为 deferdeferred,这些名称有时也用于生态系统中的实用函数。本提案采用更具描述性的名称,以方便可能不熟悉这些历史函数的用户。

    现有实现

    库和应用程序不断重复造轮子。以下只是少数示例。