簡體   English   中英

可觀察的等待方法完成

[英]Observable wait for a method to complete

我想並行運行方法A和B,一旦它們都完成,我想運行方法C。

如何使用Observable在javascript中實現此目標?

main() {

    this.methodA();
    if(some_condition) this.methodB();
    this.methodC();

}

methodA() {
    setTimeout( () => { console.log("doing some work A"); }, 500);
}

methodB() {
    setTimeout( () => { console.log("doing some work B"); }, 250);
}

methodC() {
    console.log("should be the last...");
}    

預期輸出(如果some_condition為false):

做一些工作A

應該是最后一個...

預期輸出(如果some_condition為true):

做一些工作

做一些工作B

應該是最后一個...

預期輸出(如果some_condition為true):

做一些工作B

做一些工作

應該是最后一個...

雖然我同意似乎可以最好地使用諾言來完成您的規范,但我想我會使用Observables給您一個答案,看看您的要求是什么。

本質上,只需使用merge運算符,使methodB() methodA()methodB()返回可觀察對象,並在它們全部完成時調用methodC()

var some_condition = true
function main() {
    let test$ = a()
    if (some_condition) test$ = test$.merge(b())
    test$.subscribe(console.log, null, c)
}
function a() {
    return Rx.Observable.timer(500)
        .mapTo('doing some work A')
}
function b() {
    return Rx.Observable.timer(250)
        .mapTo('doing some work B')
}
function c() {
    console.log('should be the last...')
}
main()

記錄:

doing some work B
doing some work A
should be the last...

最好的選擇是使用Promise ,它允許異步運行功能,然后在完成時觸發某些功能。 這樣做的好處是可以組成承諾,這樣您就可以在完成某些工作之前等待它們中的任何一個或全部解決。

使用ES7的異步功能/等待:

 async function main() { await this.methodA(); if(true || some_condition) await this.methodB(); await this.methodC(); } async function methodA() { console.log("doing some work A"); await timer(1000); console.log("finished A"); } async function methodB() { console.log("doing some work B"); await timer(1000); console.log("finished B"); } async function methodC() { console.log("should be the last..."); } function timer(time){ return new Promise(function(res){ setTimeout(res,time); }); } main(); 

人們可能會忘記Observable.if()的隱藏的寶石。

Observable.if(condition, thenSource, [elseSource])接受3個參數。 第一個參數是布爾條件,第二個參數是條件為true時要發出的Observable,最后一個參數是else源的數組,如果條件為false則將被發射。

如果要完全觀察可觀察到的代碼,可以采用以下方法:

1.讓所有方法都返回一個Observable

const methodA = () => {
    return Observable
        .timer(500)
        .do(() => {
            //do your work A here
            console.log('doing some work A');
        })
};

const methodB = () => {
    return Observable
        .timer(250)
        .do(() => {
            //do your work B here
            console.log('doing some work B');
        })
};

const methodC = () => {
    console.log("should be the last...");
};

2.使用Observable.if()解析流

現在,在您的主體中,只需使用Observable.if()來檢查條件是否為true,並相應地發出Observable:

const main = () => {
    let some_condition = true;
    Observable
        .if(
            //a function that returns true or false
            () => some_condition,
            //Observable to emitif condition is true
            methodA().switchMap(() => methodB()),
            //Observable to emit if condition is false
            methodA()
        )
        .subscribe(() => {}, error => {}, methodC)
};

這是為您工作的JSBin

有關Observable.if()的更多信息: https : //github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/if.md

正如@CozyAzure所說, Observable.if()是您想要的。 確保使用Observable.merge()Observable.concat()

const methodA = () => Observable.timer(500).mapTo("doing some work A")
const methodB = () => Observable.timer(250).mapTo("doing some work B")
const methodC = () => Observable.of("should be the last...")

const main = (some_condition) =>
  Observable.if(
    () => some_condition,
    methodA().merge(methodB()),
    methodA()
  )
  .concat(methodC())
  .subscribe(console.log)

main(true)

這是jsfiddle中的示例

如果您正在處理諾言,則可能要推遲創建諾言。 例如,

const methodA = () => Observable.timer(500).mapTo("doing some work A")
const methodB = () => Observable.timer(250).mapTo("doing some work B")
const methodC = () => Promise.resolve("should be the last...")

Observable.merge(methodA(), methodB())
  .concat(Observable.defer(() => methodC())
  .subscribe(console.log)

暫無
暫無

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

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