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

Ang*_*ant 3 javascript typescript ngrx angular

我有一些看起来像的代码

//service.ts

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

//component.ts

addAllproducts(productsIds) {
   productIds.forEach(productId => service.addProduct(productId);
}
Run Code Online (Sandbox Code Playgroud)

我想要的是能够在调用下一个productId之前等待每个调用完成,而不使用window.setTimeout..

Coz*_*ure 6

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

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

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

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

//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));
Run Code Online (Sandbox Code Playgroud)

这是一个有效的JSBin

使用.expand运营商的好处:

  1. 您仍在使用Observables并可以链接您想要的任何运算符.
  2. 你正在呼叫一个接一个的http,这是你的要求.
  3. 您不必担心错误处理,它们都链接到单个流.只需.catch给你的观察者打电话.
  4. 你可以对你的递归方法做任何事情(数据处理等)
  5. 您可以设置何时终止递归调用的条件.
  6. 单线(几乎)代码.

编辑

.take()如果你不喜欢内联三元,你可以使用operator来终止你的递归,如下所示:

let reduced = recursiveAddProduct(productIds[0],0,productIds)
    .expand(res=>recursiveAddProduct(productIds[res.index],res.index,productIds))
    .take(productIds.length)
Run Code Online (Sandbox Code Playgroud)

工作JSBin


Sar*_*ana 3

首先从您的服务方法返回可观察值:

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

并使用递归函数并在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())
Run Code Online (Sandbox Code Playgroud)