簡體   English   中英

Javascript:拋出異步鏈接方法

[英]Javascript: Throw in async chained methods

我有一個類返回幾個鏈接的方法,如下所示:

class MyClass{
  foo(){
    if(condition) return this;
    else throw;
  }

  bar(){
    if(condition) return this;
    else throw;
  }
}

條件是某些檢查可能是真或假,取決於類的內部狀態

我的想法是我可以執行以下幾種方法:

myInstance.foo().bar();

這樣,如果任何方法中的任何條件都失敗,則此語句將引發錯誤。

但是,現在我正在嘗試檢查需要解決的承諾的條件:

class MyClass2{
  asynCheck(){
     myPromise.then((condition)=>{
        ... // returning a promise won't work
     });

我想保持與以前相同的語法(添加await / then),我不介意將foo和bar改為異步,只要以下語法有效:

await myInstance.foo().asyncCheck().bar();

有辦法做到這一點嗎? 請注意,可能有多個asyncCheck,可以按任何順序調用

你可以用一些主要的黑客來做這件事......

 class MyClass { foo() { const ret = new Promise((resolve, reject) => { resolve(1); }) ret.bar = this.bar.bind(this); return ret; } bar() { const ret = new Promise((resolve, reject) => { resolve(2); }) // hack `ret` to copy the methods over... return ret; } } (async() => { const c = new MyClass; console.log(await c.foo()) console.log(await c.foo().bar()) })() 

您可以使用內部Promise字段實現此目的,並在每次調用方法時重新分配它:

 class MyClass { constructor(promise) { if (!promise) this.promise = Promise.resolve(); else this.promise = promise; } foo(condition) { this.promise = this.promise.then(() => { console.log("foo"); if (!condition) throw 'foo error'; }); return this; } bar(condition) { this.promise = this.promise.then(() => { console.log("bar"); if (!condition) throw 'bar error'; }); return this; } asynCheck(conditionPromise) { this.promise = this.promise.then(() => { return conditionPromise.then(condition => { console.log("asynCheck"); if (!condition) throw 'asynCheck error'; }); }); return this; } catch(callback) { this.promise.catch(callback); } } let instance = new MyClass(); instance.foo(true) .asynCheck(new Promise((res, rej) => setTimeout(() => res(true), 2000))) .bar(true) .asynCheck(new Promise((res, rej) => setTimeout(() => res(false), 3000))) .foo(false) .catch(e => console.log(e)); 

經過大量測試后,我找到了一個可能的解決方案,用Promise擴展了類,結果是這樣的:

class MyClass extends Promise {
  constructor(executor){
    super((resolve, reject)=>{return executor(resolve,reject)});
  }
  foo(){
    return new MyClass((resolve, reject)=>{
      this.then(()=>{
        if(condition) resolve();
        else reject();
      }).catch(()=> reject());
    })
  }

  asyncCheck(){
    return new MyClass((resolve, reject)=>{
      this.then(()=>{
         asyncCondition.then((condition)=>{
             if(condition) resolve();
             else reject();
         });
      }).catch(()=> reject());
    })
  }
}
const bar=new MyClass((r)=>{r()});
await bar.foo().asyncCheck();

主要的權衡是構造函數需要一個虛擬回調,因為擴展的promises如何工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM