在for循环中以角度2链接http调用

时间:2017-07-11 12:52:31

标签: javascript angular typescript ngrx

我有一些看起来像

的代码
//...
unsigned long RClock (bool reset, bool pause)
{
  unsigned long Ctime=millis();
  if(reset)
  {
    time_B=Ctime;
    //Serial.println("reset");
  }
  if(pause)
  {
    time_B=Ctime-time_E;
    //Serial.println("pause");
  }
  time_E=Ctime-time_B;
  return time_E;  
}
//...

我想要的是能够在调用下一个productId之前等待每个调用完成,而不使用//service.ts addProduct(productId) { this.http.post('someUrl', ReqData).map(json).subscribe(doStuff); } //component.ts addAllproducts(productsIds) { productIds.forEach(productId => service.addProduct(productId); } ..

3 个答案:

答案 0 :(得分:6)

使用.expand()进行一些递归调用怎么样?

首先,创建一个递归函数并映射数据以便递归使用:

const recursiveAddProduct = (currentProductId, index, arr)=>{
    return service.addProduct(currentProductId)
        .map((response)=>{
            return {
                data:response,
                index: index+1,
                arr:arr
            }
        })
};

现在,在组件中递归调用它:

//productIds is an array of Ids    
//start of using the first index of item, where index = 0

let reduced = recursiveAddProduct(productIds[0],0,productIds)
    .expand((res)=>{
        return res.index>res.arr.length-1 ? Observable.empty(): recursiveAddProduct(productIds[res.index],res.index,productIds)
    });

reduced.subscribe(x=>console.log(x));

这是一个有效的JSBin

使用.expand运算符的好处:

  1. 您仍在使用Observables并且可以链接您想要的任何运算符。
  2. 您正在呼叫一个又一个http,这是您的要求。
  3. 您不必担心错误处理,它们都被链接到单个流。只需向您的观察者调用.catch
  4. 您可以对递归方法(数据操作等)执行任何操作
  5. 您可以设置何时终止递归调用。
  6. 一行(几乎)代码。
  7. 修改

    如果您不喜欢内联三元组,可以使用.take()运算符来终止递归,如下所示:

    let reduced = recursiveAddProduct(productIds[0],0,productIds)
        .expand(res=>recursiveAddProduct(productIds[res.index],res.index,productIds))
        .take(productIds.length)
    

    工作JSBin

答案 1 :(得分:1)

首先从服务方法返回observable:

addProduct(productId) {
   return this.http.post('someUrl', ReqData).map(json).subscribe(doStuff);
}

使用递归函数并在subscribe回调中为数组中的每个项调用它:

let loop = (id: number) => {
  service.addProduct(id)
    .subscribe((result) => {
      // This logic can be modified to any way you want if you don't want to mutate the `producIds` array
      if (productIds.length) {
        loop(productIds.shift())
      }
    })
}

loop(productIds.shift())

答案 2 :(得分:0)

您可以使用Observable.merge()。 尝试类似的东西

addProduct(productId):Observable<Response> {
   return this.http.post('someUrl', productId);
}

addAllproducts(productsIds) {
   let productedsObservable:Observable<Response>[]=[];
   for(let productID in productsIds){
    this.productedsObservable.push(this.addProduct(productID));
   }
   return Observable.merge(productedsObservable)
}

您需要为其执行http请求订阅所请求的函数。 您可以阅读有关组合运算符的更多信息(例如合并)here