【问题标题】:How to combine builder pattern with async method calls in JavaScript?如何将构建器模式与 JavaScript 中的异步方法调用结合起来?
【发布时间】:2020-10-26 19:13:27
【问题描述】:

我想实现像这样的链式方法调用

observable
 .pipe(
  filter('foo'),
  add(3)
 )
 .subscribe(subscriber);

为了使其工作,.pipe(...) 的结果必须提供方法subscribe

我想允许async 调用一些链式方法调用(例如pipe)。但是,这会破坏我的链条,因为pipe 返回的承诺没有subscribe 方法:

await observable
 .pipe(
  filter('foo'),
  add(3)
 )
 .subscribe(subscriber);

async pipe(...operators){
  ...
}

=> Uncaught (in promise) TypeError: observable.pipe(...).subscribe is not a function

我可以将我的主要代码重写为

observable
 .pipe(
  filter('foo'),
  add(3)
 ).then(pipeResult=>
  pipeResult.subscribe(subscriber);
 );

但是,我觉得这很难读。

=> 有没有办法为方法调用链中的每个调用应用await 而不仅仅是最后一个调用?

我会期待类似的东西

awaitEach observable
 .pipe(
  filter('foo'),
  add(3)
 )
 .subscribe(subscriber); 

编辑

  • 相关问题:

chaining async method calls - javascript

  • 在 Promises 的帮助下,我可以从同步调用转换为异步调用:

foo(){
 return new Promise(resolve=>{
   baa().then(arg=>resolve(arg))
 })
} 

但是,我需要另一个方向,例如:

pipe() {
   var result = undefined;
   await asyncCall(()=>{ //await is not allowed here; forces pipe to by async
     result = 5;
   });
   return result;
 }

【问题讨论】:

  • 它在 rxjs 中是可行的,例如 mergeMap 运算符。你可以查看他们的源代码,看看他们是如何解决这个用例的。

标签: javascript async-await reactive-programming builder


【解决方案1】:

作为一种解决方法,我使用subscribe 代理扩展了生成的承诺,调用了我实际的subscribe 方法:

pipe(...operators){

    let observable = this;

    let promise = new Promise(async (resolve) =>{
      for (let operator of operators){
       observable = await this._applyOperator(operator, observable);
      }
      resolve(observable);
    });

    promise.subscribe = (subscriber)=>{
      promise.then(resultingObservable =>{
        resultingObservable.subscribe(subscriber);
      })
    };

    return promise;
} 

如果您知道更好的解决方案,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-31
    • 2013-12-20
    • 1970-01-01
    • 1970-01-01
    • 2017-01-17
    • 1970-01-01
    • 2012-01-02
    • 2013-12-14
    相关资源
    最近更新 更多