首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >链式观测

链式观测
EN

Stack Overflow用户
提问于 2018-03-29 17:34:05
回答 1查看 312关注 0票数 1

我知道这已经被问了几次,但我找不到一个解决方案,实际上在角5与rxjs5。

TL;DR;如何使这4个可观测值按顺序同步运行:

代码语言:javascript
复制
    const getImage$ = this.fileService.getImage(this.shape.imageFile.id);
    const getUrl$ = Observable.create((blob: Blob) => {
        return URL.createObjectURL(blob);
    });
    const fromURL$ = Observable.bindCallback(fabric.Image.fromURL);
    const addImage$ = Observable.create((img: any) => {
        this.shapeElement = img;
        this.shapeGroup = new fabric.Group([this.shapeElement], {
            lockScalingFlip: true,
            centeredRotation: true,
            angle: this.shape.rotation
        });
        this.fabric.add(this.shapeGroup);
    } );

然后返回可观察到的内容,这样我就可以在订阅者中做更多的事情。

更长的版本..。

我有一个文件服务,它请求一个图像并返回一个可观察到的blob:

代码语言:javascript
复制
getImage(id) => Observable<Blob>

然后我需要得到这个blob的url:

代码语言:javascript
复制
URL.createObjectURL(blob)

THen我需要将它加载到一个带有回调函数的FabricJS画布中。我由此创造并观察到:

代码语言:javascript
复制
fromURL = Observable.bindCallback(fabric.Image.fromURL)

最后,在返回可观察到的内容之前,我需要修改由Fabric创建的图像对象--订阅有更多的内容可以更新ui。

代码语言:javascript
复制
this.shapeGroup = new fabric.Group([this.shapeElement], {
   lockScalingFlip: true,
   centeredRotation: true,
   angle: this.shape.rotation,
   tag: Date.now()
  });
this.shapeGroup.shapeView = this;
this.shapeGroup.setShadow(this.getShadow());
this.canvas.fabric.add(this.shapeGroup);

这就是我迷路的地方。我试着理解了mergeMap、地图、管道以及其他一些东西,但我无法做到这一点。

这里有人做过这种事吗?实现这一点似乎过于复杂了。

首先,我得到了这个:

代码语言:javascript
复制
draw(): Observable<ImageView> {  

  const fromURLOb = Observable.bindCallback(fabric.Image.fromURL);

  return Observable.create(o => {
    if (this.shape.imageFile) {
      console.log('started loading');               
      o.next(this.fileService.getImage(this.shape.imageFile.id));
    }
    o.complete();
  })
 ...

这是可行的,但之后,我失去了。

解决方案!

感谢@Ingo,这是我的工作版本。

代码语言:javascript
复制
    draw(): Observable<ImageView> {
      return this.fileService.getImage(this.shape.imageFile.id)
        .map(blob => URL.createObjectURL(blob))
        .switchMap<string, any>(url => {
            return Observable.bindCallback(fabric.Image.fromURL).call(this, url);
        })
        .do<ImageView>(image => {
            this.handleImage(image);
            return this;
        });
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-03-30 15:09:07

这里发生了几件事:

  1. URL.createObjectURL实际上只是一个同步函数,它不会返回一个可观察到的函数。因此,您只需使用mapgetImage的结果映射到URL。
  2. fromUrl调用确实使用回调,因此您可以像以前一样使用bindCallback;但是,bindCallback并不返回可观察的(如您所指出的),而是返回返回可观察到的函数。因此,您需要使用您获得的URL调用该函数;您可以在这里使用switchMap或其变体之一;因为您只处理“发射一次并完成”可观测性,所以这些变体之间的差异并不重要。
  3. 您正在做的最后处理实际上只是一个副作用,它不影响您想要返回的值,因此您可以只使用do操作符来执行一个副作用。
  4. 您对Observable.create的使用表明了一些误解。传递给Observable.create的函数总是接收一个观察者作为参数,而不是某个值。我觉得你把函数和观察都搞混了。

因此,您可以这样做:

代码语言:javascript
复制
private handleImage(img: any) {
    this.shapeElement = img;
    this.shapeGroup = new fabric.Group([this.shapeElement], {
        lockScalingFlip: true,
        centeredRotation: true,
        angle: this.shape.rotation
    });

    this.fabric.add(this.shapeGroup);
}

draw() {
  return this.fileService.getImage(this.shape.imageFile.id)
    .map(blob => URL.createObjectURL(blob))
    .switchMap(url => Observable.bindCallback(fabric.Image.fromURL)(url))
    .do(image => this.handleImage(image));
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49562074

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档