Observable等待方法完成

时间:2017-07-11 15:35:54

标签: javascript rxjs observable

我想并行运行方法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为真):

做一些工作A

做一些工作B

应该是最后一个......

预期输出(如果some_condition为真):

做一些工作B

做一些工作A

应该是最后一个......

5 个答案:

答案 0 :(得分:2)

虽然我同意你的规范似乎最好用promises来完成,但我想我会用Observables给你一个答案,看看你的要求是怎样的。

基本上,只需使用merge运算符,使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...

答案 1 :(得分:1)

您最好的选择是使用Promise允许函数异步运行,然后在完成后触发某些功能。这样做的好处是可以组成承诺,以便您可以在完成某些工作之前等待其中的任何一个或全部解决。

答案 2 :(得分:1)

使用ES7s异步功能/等待:

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();

答案 3 :(得分:1)

人们可能会忘记Observable.if()的隐藏宝石。

Observable.if(condition, thenSource, [elseSource])接受3个参数。第一个参数是布尔条件,第二个参数是条件为真时要发出的Observable,最后一个是else源数组,如果条件为假则将被释放。

如果你想完全使用Observable-lised你的代码,你可以这样做:

<强> 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()解析流

现在,在您的main中,只需使用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

答案 4 :(得分:1)

正如@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)