如何从XHR创建Observable

时间:2016-11-09 15:23:13

标签: angular rxjs observable

我正在尝试在Angular2中上传文件。我使用了我在这里找到的代码 - https://plnkr.co/edit/ozZqbxIorjQW15BrDFrg?p=info

我需要在我的史诗(Angular2 + Redux)中使用响应,所以我想做类似的事情:

updateAvatarRequest = (action$: ActionsObservable<IPayloadAction>) => {
    return action$.ofType(MeActions.UPDATE_AVATAR)
      .mergeMap<IPayloadAction>(({payload}) => {
        return this.meService.updateAvatar()
          .map(result => ({
            // ACTION ON SUCCESS
          }))
          .catch(error => Observable.of({
            // ACTION ON ERROR
          }));
        });
}

问题是我没有得到Observable的任何回复,直到我没有订阅它。另一个问题是我无法在这个observable上使用catch()。如果我这样做,它就有效:

this.meService.updateUserAvatar(formData)
    .subscribe(
      (x) => console.log('onNext: %s', x),
      (e) => console.log('onError: %s', e),
      () => console.log('onCompleted')
);

但我希望保持一致。请帮助我使用这个RxJS,直到我失去剩余的头发。

1 个答案:

答案 0 :(得分:2)

  

在我不订阅之前,我没有得到Observable的任何回复

这是设计的。我想action$.ofType(MeActions.UPDATE_AVATAR)会返回一个冷的Observable,因此在至少有一个订阅者之前不会触发它。您可以使用publish()将其转换为ConnectableObservable,然后立即致电connect(),这会使其成为热门观察者(https://jsbin.com/faquhew/5/edit?js,console),但我认为坚持下去会更好使用默认功能。

有关详细信息,请参阅:

运营商catch()让您通过其回调返回的Observable继续链接,请参阅:https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/catch.md

因此,这取决于您希望通过catch()实现的目标。

编辑:

var source = Observable.create(obs => {
    obs.next(1);
    obs.next(2);
    obs.error(new Error('original error message'));
  })
  .catch(error => Observable.of('recovered from error'));

source.subscribe(val => console.log(val));

打印到控制台:

1
2
"recovered from error"

查看现场演示:https://jsbin.com/micebeg/4/edit?js,console