在angular 7中循环运行时,如何确保http post已完全执行?

在angular 7中循环运行时,如何确保http post已完全执行?,angular,Angular,我在angular 7中的一个循环中调用HTTP POST。如何确保saveMembers()和saveTasks()已完全执行?我希望这两项工作同时进行 function saveMembers() { // Add resource members.forEach(resource => { this.addMembers(resource.name); }); } function saveTasks() { // Add tasks

我在angular 7中的一个循环中调用HTTP POST。如何确保saveMembers()和saveTasks()已完全执行?我希望这两项工作同时进行

function saveMembers() {
    // Add resource
    members.forEach(resource => {
        this.addMembers(resource.name);
    });
}

function saveTasks() {
    // Add tasks
    tasks.forEach(task => {
        this.addTasks(task.name);
    });
}

function addMembers(resourceName) {
    this.http.post(this.apiUrl + 'Members', { "name": resourceName }).
        subscribe((data) => { console.log(data); }, (error) => { });
}

function addTasks(taskName) {
    this.http.post(this.apiUrl + 'Task', { "task": taskName }).
        subscribe((data) => { console.log(data); }, (error) => { });
}

通常情况下,http命令是使用可观察对象执行的,这似乎也是您的情况

在您的代码中,您创建的可观察对象数量与
成员
任务
的数量相同,然后分别订阅它们中的每一个。考虑到http调用的异步性质,您最终不知道处理何时完成

另一方面,如果您希望在所有观测完成时收到通知,那么您可以使用
forkJoin
函数,代码如下所示

function saveMembers$() {
    // Returns an array of Observables, each one representing an Http Post
    return members.map(resource => {
        return this.addMembers(resource.name);
    });
}

function saveTasks$() {
    // Returns an array of Observables, each one representing an Http Post
    return tasks.map(task => {
        return this.addTasks(task.name);
    });
}

function addMembers$(resourceName) {
    return this.http.post(this.apiUrl + 'Members', { "name": resourceName }).
        pipe(catchError(err => {
          // create a structure with the relevant error info
          const errStructure = ....
          // return an Observable which emits the errStructure
          return of(errStructure);
        });
}

function addTasks(taskName) {
    return this.http.post(this.apiUrl + 'Task', { "task": taskName }).
        pipe(catchError(err => {
          // create a structure with the relevant error info
          const errStructure = ....
          // return an Observable which emits the errStructure
          return of(errStructure);
        });
}

// finally execute all the Post in parallel with forkJoin
forkJoin([...saveMembers$(), ...saveTasks$()]).subscribe(
  resp => {
     // resp is an array containing either the value returned by the post
     // or the error info. resp follows the same order as the Observables passed
     // to forkJoin
  }
)

您可以按照以下思路做一些事情:

import { of } from "rxjs";
import { mergeAll } from "rxjs/operators";

const members = [1, 2, 3, 4, 5];
const tasks = [11, 22, 33];

function saveMembers() {
  const stream = of(...tasks.map(task => addMembers(task)));
  stream
    .pipe(mergeAll())
    .subscribe(
      val => console.log("saving task", val),
      () => console.log("error"),
      () => console.log("completed saving tasks")
    );
}

function saveTasks() {
  const stream = of(...members.map(member => addMembers(member)));
  stream
    .pipe(mergeAll())
    .subscribe(
      val => console.log("saving member", val),
      () => console.log("error"),
      () => console.log("completed saving members")
    );
}

function addMembers(resourceName) {
  // Faking the observable using rxjs 'of' utility
  // Note that you don't want to subscribe to the observable yet
  return of(resourceName);

  // return this.http.post(this.apiUrl + 'Members', { "name": resourceName });
}

function addTasks(taskName) {
  // Faking the observable using rxjs 'of' utility
  // Note that you don't want to subscribe to the observable yet
  return of(taskName);

  // return this.http.post(this.apiUrl + 'Task', { "task": taskName });
}

saveMembers();
saveTasks();
因此,在
saveMembers()
中,我通过将调用映射到
addMembers()
来创建一个可观察的数组。然后,我使用rxjs的
实用程序从观察值数组中创建一个流。然后我输入
mergeAll
操作符并订阅新流。一旦流中的所有可观察对象完成,流本身也将完成。因此,在对
subscribe()
函数的第三次回调中,您可以在所有帖子完成后放置逻辑。 您可以找到更多关于rxjs操作符的信息,如
mergeAll

我正在使用rxjs的
实用程序的
伪造
addMembers()中的异步POST请求。您必须返回可观察的实际POST请求,但确保不订阅它。它将在
saveMembers()
函数中订阅。通常,您返回的语句在
addMembers()
中被注释掉


您应该确保在
addTasks
函数中以及调用函数的
map
s中返回可观测值。您是对的-我现在修复了它,否则,回答就太好了。解释得很好!