2017-01-15 73 views
0

我想使用返回可观察对象的方法来转换和替换数组中的所有单词。我使用基于this answer的绑定来传递正确的值。等待一组可观察的订阅函数完成

当所有订阅完成后,我想调用另一个函数task2()。我怎样才能实现这个?

for(let word in this.words){ 
    var i = Object.keys(this.words).indexOf(word); 

    this.convertor.get(this.words[i].value).subscribe(function (i, result) { 
    this.words[i].value = result; 
    }.bind(this, i)); 
} 

//task2() <--------- when all subscribe functions finished 
+0

的可能的复制(http://stackoverflow.com/questions/35608025/promise-all-behavior -with-rxjs-observables) –

回答

1

什么类型是this.words?如果它是一个数组,那么它更容易循环他们的物品...你正在做的事情真的很奇怪...

此外,请考虑使用箭头功能,以避免在任何地方使用bind(this)。它有助于读出代码。

你应该使用forkJoin重写代码:[?与RxJS观测量Promise.all行为]

let streams = []; 
for(let i = 0; i<this.words.length; i++){ 
    streams.push(this.convertor.get(this.words[i].value)); 
} 

Rx.Observable.forkJoin(streams).subscribe((result) => { 
    // Here result is an array with the results, and it's sorted properly (The first result is from the first stream, and so on). 
    for(let i=0; i<result.length; i++) { 
     this.words[i].value = result[i]; 
    } 

    task2(); 
}); 
+0

不错的建议!我只有一个担心:这段代码的运行时间与使用绑定的情况相比如何。看起来像你第一次推动一个数组(流)的一切。如果这个阵列太大了会怎么样? – Ari

+0

@Ari'bind'在内部返回一个函数,该函数将设置'this'并将任何参数传递给您定义的函数。由于我们不需要使用此解决方案的任何附加参数,并且可以使用箭头函数设置“this”,所以我们不需要它。我不太确定使用数组的效果......测试/基准测试可能会很有趣。让'.subscribe('进入一个巨大的重复循环也不太好。 – olivarra1

0

我的模板解决方案:生成功能,只有在N调用(如Promise.all)

像这样调用另一个函数:

function onlyNthCall(callCount, callback) 
 
    { 
 
    var callIter = 0; 
 
    return function() 
 
     { 
 
     callIter++; 
 
     if(callIter === callCount) { callback(); } 
 
     } 
 
    } 
 
var task2AfterLastCall = onlyNthCall(Object.keys(this.words).length, task2); 
 

 
for(let word in this.words){ 
 
    var i = Object.keys(this.words).indexOf(word); 
 

 
    this.convertor.get(this.words[i].value).subscribe(function (i, result) { 
 
    this.words[i].value = result; 
 
    task2AfterLastCall(); 
 
    }.bind(this, i)); 
 
}