2016-12-26 38 views
0

我想知道是否有辦法在平坦的承諾中轉變連鎖承諾。我有這樣的代碼:如何在Q和TypeScript中將連鎖承諾變成公平承諾

import * as Q from 'q'; 
export class MyClass { 

    private methodA(): Q.Promise<boolean> { 
    let deferred = Q.defer<boolean>(); 
    //some stuff, like database calls, etc 
    return deferred.promise; 
    } 

    private methodB(): Q.Promise<boolean> { 
    let deferred = Q.defer<boolean>(); 
    //some stuff, like database calls, etc 
    return deferred.promise; 
    } 

    private methodC(): Q.Promise<boolean> { 
    let deferred = Q.defer<boolean>(); 
    //some stuff, like database calls, etc 
    return deferred.promise; 
    } 

    private methodD(): Q.Promise<boolean> { 
    let deferred = Q.defer<boolean>(); 
    //some stuff, like database calls, etc 
    return deferred.promise; 
    } 

    run(): Q.Promise<boolean> { 
    let deferred = Q.defer<boolean>(); 
    let promises = []; 

    promises.push(this.methodA().then(wasOk => { 
     this.methodB().then(wasOk => { 
     this.methodC(); 
     }); 
    })); 

    promises.push(this.methodD()); 

    //Wait all promises 
    Q.all(promises).then(wasOk => deferred.resolve(wasOk)); 

    return deferred.promise; 
    } 
} 

此代碼有一個問題:Q.all只等待methodA和methodD;並沒有等待methodB和methodC。

我想我需要將方法B和C放在承諾的向量中,甚至可以創建另一個向量並在第一個內部等待它Q.all ...但它不是一個明確的代碼,我想知道是否有一個更好的方法。

非常感謝!

回答

2

你只是缺少一個在returnmethodAthen處理程序,並且有可能在其then處理程序,因爲您正在使用詳細信息箭頭功能:

promises.push(this.methodA().then(wasOk => { 
    return this.methodB().then(wasOk => { 
//^^^^^^^ 
    return this.methodC(); 
// ^^^^^^^ 
    }); 
})); 

或用簡潔箭頭功能:

promises.push(this.methodA().then(wasOk => this.methodB().then(wasOk => this.methodC()))); 

還是以簡潔的箭頭與換行符:

promises.push(this.methodA().then(wasOk => 
    this.methodB().then(wasOk => 
    this.methodC() 
) 
)); 

注意,該代碼執行此操作:

  • 呼叫methodA並等待它來解決,然後
  • 呼叫methodB,等待它來解決,然後
  • 呼叫methodC

所以,總體來說,您的數組中的第一個承諾不會解決,直到methodBmethodC解決;立即致電methodD,因此可以儘快解決。

的陣列結構可能很簡單,以及:

promises = [ 
    this.methodA().then(wasOk => 
    this.methodB().then(wasOk => 
     this.methodC() 
    ) 
), 
    this.methodD() 
]; 
+0

你是對的。在我原來的代碼中,方法B和C從未被調用過。我的問題是,在這個鏈中,方法B和C只需要根據父承諾的結果進行調用,所以我需要大括號將一些「if」放入其中。我會用更真實的代碼更新我的問題。謝謝! –

+0

@VladimirVenegas:以上允許'methodB'使用'methodA'的結果,並允許'methodC'使用'methodA'和'methodB'的結果。唯一不在鏈中的(並行)是'methodD'。 –

1

你有輕微的錯誤,幾乎是一個錯字:

promises.push(this.methodA().then(wasOk => { 
     this.methodB().then(wasOk => { 
     this.methodC(); 
     }); 
    })); 

它的花括號 - 他們改變的回報承諾的到的不確定回報。你可以這樣做:

promises.push(this.methodA().then(wasOk => 
     this.methodB().then(wasOk => 
     this.methodC(); 
    ); 
    )); 

或本:

promises.push(this.methodA().then(wasOk => { 
     return this.methodB().then(wasOk => { 
     return this.methodC(); 
     }); 
    })); 

,甚至這樣的:

promises = [this.methodA(), this.methodB(), this.methodC()];