Observable.expand并使用数组使用mergeMap创建一个基于observable的请求?

时间:2018-05-30 05:32:02

标签: angular rxjs observable

我有一个可以是多个请求的查询,每个请求都是一个可观察的,并且正在使用.expand递归查看每个observable并发出请求。

当对象的计数为> 1我们继续做一个post请求并创建一个obj,如果count为0,我们删除刚刚创建的obj。这部分代码已经存在

我需要帮助才能使其不是通过其ID删除每个对象,而是将所有ID推送到数组,然后使用id' s发送批量删除请求作为有效载荷。

我尝试使用switchMap,但不确定是否需要在.expand之外完成,或者observable有更好的方法来执行此操作吗?

我也有deleteById的方法。

在以下现有代码中,您能否帮助解决这方面的需求

   return new Promise((resolve, reject) => {
    let temp = [];
    let obj = {};
    let queryIds = [];
    this.restService.observable.post(CREATE, val).expand(response => {
        obj = response.json();
        if (obj && obj.Count > 0) {
            return this.restService.observable.get(`${GET_NEXT}?id=${obj.id}`);
        } else if (obj && obj.Count === 0) {
            //returns an observable of each obj's id for delete request
            //return this.restModuleService.observable.get(`${DELETE}?id=${obj.id}`);
            //instead need to push the id's into an array 
            and make a delete request on teh array of ids
            //queryIds.push(obj.id);
            //return Observable.empty();

        } else {
            return Observable.empty();
        }
    })**.toArray().mergeMap(objects => {
            const objArray = objects.map(obj => obj.json());
            const toDelete = objArray.filter(obj => obj.remainingCount === 0);
            return this.deleteByIds(toDelete);
    })**.map(res => res.json()).subscribe(data => {
        if (data) {
            temp.push.apply(temp, data.results);
        }
    });

);

deleteById方法

   deleteByIds(queryIds, cb) {
    var data = {
        data: {
            ids: []
        }
    };
    for (var i = 0; i < queryIds.length; i++) {
        data.data.ids.push(queryIds[i]);
    }
    let payload = JSON.stringify(data);
    return this.restService.post('deleteBulk', payload)
        .then(response => response.json())
        .catch((error) => {
        });
}

1 个答案:

答案 0 :(得分:1)

您在展开操作中发出的每个值都会在您的流中流淌。因此,您可以执行初始请求,在需要时展开所有附加内容,然后将所有删除累积到一个操作中,如下所示:

doRequestForObject(1)
  .expand(obj => {
    if(obj.count == 0) {
      return Rx.Observable.empty();
    }
    /* keep getting objects */
    return doRequestForObject(1 + obj.id);
  })
  .toArray()
  .mergeMap(objects => {
    /* in here objects is an array so we can use Array.filter() */
    const toDelete = objects.filter(obj => obj.count === 0);
    return deleteObjects(toDelete)
      .concat(Rx.Observable.of(objects.filter(obj => obj.count > 0)));
  })
  .subscribe(console.log, console.log, () => console.log("done"));


function doRequestForObject(i) {
  return Rx.Observable.of({
    id: i,
    count: i % 5
  });
}

function deleteObjects(idArray) {
  console.log('deleting: ' + JSON.stringify(idArray));
  return Rx.Observable.empty();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.11/Rx.js"></script>