2017-09-03 217 views
4

所以我想擴展Promise以獲得'進度'部分,以便我可以在使用Promise進行異步任務時報告程序。擴展Promise以支持進度報告

因此我伸出無極這樣的:

class promisePro extends Promise { 
    constructor(fn) { 
     super(function (resolve, reject) { 
      fn(resolve, reject, this._progress.bind(this)); 
     }); 
    } 

    _progress(v) { 
     if (this.progressCB) 
      this.progressCB(v); 
    } 

    progress(fn) { 
     this.progressCB = fn; 
    } 
} 

,並用它:

function ptest() { 
    return new promisePro((resolve, reject, progress) => { 
     setTimeout(() => { 
      progress(0.3) 
     }, 1000) 
     setTimeout(() => { 
      progress(0.6) 
     }, 2000) 
     setTimeout(() => { 
      progress(0.9) 
     }, 3000) 
     setTimeout(() => { 
      resolve(1) 
     }, 4000) 
    }) 
} 

和使用ITT:

ptest().then((r) => { 
    console.log('finiished: ' + r) 
}).progress((p) => { 
    console.log('progress: ' + p) 
}) 

,並得到這個錯誤:

ptest().then((r) => { 
    ^
TypeError: Promise resolve or reject function is not callable 

我在這裏做錯了什麼?

我正在使用節點7.5,更新到8.4。在兩個版本中都有這個錯誤。

謝謝。

+3

也許看看['progress-promise'](https://www.npmjs.com/package/progress-promise)。 – robertklep

+0

@robertklep生病看看,但不是找到一個解決方案,我想知道如何修復我的代碼,即時通訊學習節點/ JS你知道 – ajlajlajl

+1

我建議不要爲此延伸'承諾'的子類。定向進度通知在承諾方式上並不完美,它需要一個單獨的抽象(如鏈接的「progress-promise」包中的'all'和'sequence'自定義方法)。最簡單和最靈活的解決方案是將進度回調傳遞給返回正常承諾的函數。 – Bergi

回答

2

這裏有幾個問題需要注意。

首先,在調用super函數之前,「this」關鍵字是未定義的。因此,你可以在構造函數更改爲類似下面,使用函數引用一個實例變量SEL

constructor(fn) { 
    let self; 
    super(function (resolve, reject) { 
     fn(resolve, reject, value => self._progress(value)); 
    }); 
    self = this; 
} 

其次,記住要擴展的承諾類型,所以當你呼叫的「那麼」功能在它上面,它會返回一個新的承諾對象,而不是你的新承諾類型,所以進度函數在那裏是未定義的。辦法避免這一點就是回到在進度功能「本」,並在使用前,然後使用進度功能,如下

progress(fn) { 
    this.progressCB = fn; 
    return this; 
} 

和使用

ptest().progress((p) => { 
    console.log('progress: ' + p) 
}).then((r) => { 
    console.log('finiished: ' + r) 
}) 

但現在您將失去承諾的好處,並且無法將更多的承諾與進展鏈接起來(仍然取決於您的使用情況)。

作爲一種不同方法的建議,您是否嘗試過使用Observables? http://reactivex.io/rxjs/

+0

感謝的人 我不知道這是未定義超級通話之前!修復「承諾解決或拒絕功能不可調用」錯誤固定,強硬我不知道該消息與真正問題的關係是什麼...... – ajlajlajl

+0

通過刪除代碼段,特別是進度調用,你會得到一條消息說無法找到_progress的未定義的 – Tal

+0

謝謝, 至於進度鏈問題,我給我的課加了一個「then」: 然後(fn)超過(fn) 返回此; } donno如果它是一個好主意,但解決了我的問題。 考慮我是一個noob在JS中,這是一個很好的解決方案? – ajlajlajl