使用服务的循环中的Angular2顺序http请求

时间:2017-04-28 00:35:51

标签: angular

基本上我想要的是这样的:

this.accounts.forEach(account=> {
   this.myService.sendMessage("hello", account).subscribe(
   success => {
       if(success)
         updateProgress...   
   })
}

此代码的问题在于它无需等待上一个请求即异步执行所有内容。我正在使用merge和flatMap查看解决方案,但我很困惑。在转到下一次迭代之前,我想等待请求完成。如果我想添加进度条,这会导致问题。

解决方案:

基于其他答案,这就是我所提出的:

let requestList = this.accounts.map((account, index) => {
    return this.myService.sendMessage("hello", account).map(success => {
            if (success)
            {
                // Update progress here
            }
            return success;
        });
    });

Observable.concat(...requestList).subscribe(null, null, () => {
    console.log("Complete");
});

2 个答案:

答案 0 :(得分:2)

Concat操作将对您的请求进行排序:

let accounts = ['1', '2', '3', '4' ];

var i = 8000;
let obsList$= accounts.map(x=> {
   i = i - 1000;
  return Rx.Observable.of(x).delay(i);
});

Rx.Observable.concat(...obsList$)
   .subscribe(x=>console.log(x))
  1. 映射帐户以创建Observables数组。为每一个添加一个延迟,以确保第一个延迟是缓慢的(确保序列有效。
  2. Concat运算符接受一系列可观察量。所以使用...(扩展运算符)来转换数组
  3. 使用concat运算符确保下一个observable仅在前一个observable完成后才会发出。

答案 1 :(得分:1)

这是一个可能适合您的示例技术。

    // create an array of promise/resolves that will sequence the calls
    let resolveArray: Array<(value: boolean) => void> = new Array[this.accounts.length];

    this.accounts.forEach((account, index) => {
        new Promise<boolean>((resolve, reject) => {
            // add the promise to the array.
            resolveArray[index] = resolve;
        }).then(result => {
            this.myService.sendMessage("hello", account).subscribe(
            success => {
                if(success)
                    // updateProgress...   

                    // when finished, resolve the next promise in the array
                    if (index < this.resolveArray.length) {
                        this.resolveArray[index + 1](true);
                    }

            })
        });
    });

    // resolve the first promise to start the resolve sequence.
    resolveArray[0](true);

这可以通过创建一个promises数组来实现,然后在每个promise完成时触发你的订阅。