【问题标题】:How to return an extended promise instance from an async function?如何从异步函数返回扩展的 Promise 实例?
【发布时间】:2020-01-02 05:53:30
【问题描述】:

我只是在玩弄我的框架的一些想法,假设我像这样扩展了 Promise 类

class cool_promise extends Promise {
    cool_function() {
        console.log("I am cool");
    }
}

并且有一个像

这样的异步函数
async cool_function() {
    return "functioning";
}

现在默认情况下,cool_function 在同步执行时只返回一个常规 Promise,但是否可以让特定于我的框架的异步函数返回我扩展的 Promise 类?

【问题讨论】:

  • 你为什么需要那个? Promise.prototype.cool_function = function() {console.log('I am cool')} 够吗?无论如何,扩展某些类并不意味着修改基本类本身(因此当前目标无法实现)。
  • @skyboyer 它会起作用,但我宁愿避免改变香草类的原型。我希望它可以让 Promise 类在我的框架中使用起来更流畅。

标签: javascript asynchronous


【解决方案1】:

async 关键字总是会导致函数返回原生 Promise。要返回自定义 Promise,您的函数需要声明为不带 async 并直接返回 Promise。

您可以像平常一样编写异步函数,但在将它们作为框架接口的一部分公开之前,用返回 CoolPromise 的函数包装它们:

class CoolPromise extends Promise {
  coolFunction ( ) {
    return 'I am cool';
  }

  static decorate ( func ) {
    return function (...args) {
      return CoolPromise.resolve( func.call( this, ...args ) );  
    };
  }
}



// Some module with an async function in it

const module = function Module ( ) {
  async function foo( ) {
    return 'bar';
  }

  // Decorate functions before exposing them from your modules
  return {
    foo: CoolPromise.decorate( foo )
  };
}( );



// Verify that module.foo( ) returns a CoolPromise

(async ( ) => {
  console.log( await module.foo( ) );
  console.log( module.foo( ).coolFunction( ) );
})();

【讨论】:

    【解决方案2】:

    不,您必须使用 cool_promise.resolve(cool_function()) 手动转换它。如果不使用 JavaScript 预处理器,异步函数将始终返回本机 Promise

    有时另一种方法是扩展原生 Promise 原型:

    Object.defineProperty(Promise.prototype, 'cool_function', {
        configurable: true,
        writable: true,
        value() {
            console.log("I am cool");
        },
    });
    

    不过,修改全局变量总是有与其他库/用户代码冲突或以后更改语言的风险。有时最好只拥有一个独立的功能。也许有一天可以在类似于方法调用语法的管道中使用这种函数——例如,有一个提案可以让你这样做或类似的事情:

    const cool_extension = (promise) => {
        console.log("I am cool");
    };
    
    cool_function() |> cool_extension
    // cool_function().cool_extension(), when extending prototype
    

    与此同时,cool_extension(cool_function()) 还算不错,而且很熟悉。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-08
      • 2020-07-09
      • 1970-01-01
      • 2020-07-09
      • 2017-10-16
      • 1970-01-01
      • 2020-07-17
      • 2018-04-13
      相关资源
      最近更新 更多