2016-12-26 41 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()];