创建一系列承诺以供将来执行

时间:2018-08-29 14:59:02

标签: angular typescript promise

我已经创建了一个数组来存储应许列表,该应许列表应在一次调用Promise.all之后运行,但是在将这个新的Promise推入数组后立即执行。我该如何解决?

let promises: any[] = [];

this.tasklistItems.forEach(element => {
  if (element.checked) {
     promises.push(new Promise(() => this.tasklistItemsService.delete(this.tasklist, element.id))); // It gets executed right after this line
  }
});

Promise.all(promises) // But I need to start executing here
  .then((res) => { // So I can get all responses at the same place, together
    this.notification.success('Success!', 'Rows removed.');
  },
  (err) => {
  });

更新

按照@Evert的建议,现在我有以下代码:

  const deferred = [];
  this.tasklistItems.forEach(element => {
    if (element.checked) {
      deferred.push(() => this.tasklistItemsService.delete(this.tasklist, element.id).subscribe());
    }
  });

  Promise.all(deferred.map(func => func()))
    .then(
      () => {
        this.notification.success('Sucess!', 'Rows removed.');
        this.refreshGrid();
      },
      err => {
        console.log(err);
        this.notification.error('Error!', 'Could not remove the selected rows.');
      }
    );

这是我使用HttpClient的服务:

  delete(tasklistId: number, id: number): Observable<boolean> {
    return this.http.delete(`${this.baseUrl}/${tasklistId}/items/${id}`)
      .pipe(catchError(this.handleError));
  }

如果我没有将subscribe()添加到delete(...)调用中,则不会执行它,如果添加它,则在删除发生之前将调用refreshGrid()

2 个答案:

答案 0 :(得分:2)

此行中断:

new Promise(() => this.tasklistItemsService.delete(this.tasklist, element.id)

除此之外,承诺通常会立即执行。它们不是将执行推迟到以后的机制。值得庆幸的是,javascript对此非常简单:一个简单的旧函数。

const deferred = [];
this.tasklistItems.forEach(element => {
  if (element.checked) {
    deferred.push(() => this.tasklistItemsService.delete(this.tasklist, element.id)));
  }
}

// Iterates over all stored functions, calls them all and returns the result as an array of promises.
Promise.all( deferred.map( func => func() ) );

答案 1 :(得分:0)

通常,.forEach()Promise.all()不能很好地融合在一起,创建延迟承诺的数组会增加一些不必要的步骤。 (诺兰·劳森的"We have a problem with promises"在解决这两个问题上做得很好。)正如@Evert所提到的,这是因为诺言是“渴望的”,并在它们被构造后立即执行。

您似乎想获取一个数组,筛选出未选中的选项,然后从中解决一个promise数组。直接在.filter()中使用.map()Promise.all()怎么样?

Promise.all(
  this.tasklistItems
    .filter(element => element.checked)
    .map(checkedElement => this.tasklistItemsService.delete(this.tasklist, checkedElement.id)
)
.then((res) => { // So I can get all responses at the same place, together
  this.notification.success('Success!', 'Rows removed.');
},
(err) => {});