Angularjs   发布时间:2022-04-20  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了使用Angular2 / RxJS读取缓冲响应大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在建立一个从后端读取数据的网站.该数据即时计算并以缓冲方式发送回客户端.即一旦计算出第一个块,就会将其发送到客户端,然后计算下一个块并将其发送给客户端.整个过程发生在同一个http请求中.客户端不应该等待完成响应完成,而是在发送后立即自己处理每个块.通常可以使用XHR进度处理程序(例如 How to get progress from XMLHttpRequest)来消费这样的响应.

如何使用RxJS和Observables在Angular2中使用httpR_988_11845@odule消耗这样的响应?

编辑:peeskillet在下面给出了一个非常详细的答案.另外,我做了一些进一步挖掘,发现了feature request for the HttpModule of AngularStackOverflow question with another approach on how to solve it.

解决方法

注意:以下答案仅为POC.它旨在教育http的体系结构,并提供简单的工作POC实现.我们应该看一下 XHRConnection的来源,了解在实施时应该虑的其他内容.

在尝试实现这一点时,我认为没有任何方法可以直接进入XHR.看起来我们可能需要提供使用http所涉及的一些组件的自定义实现.我们应该虑的三个主要组成部分是

>连接
> ConnectionBACkend
> http

http将ConnectionBACkend作为其构造函数的参数.当发出请求时,比如get,http与ConnectionBACkend.createConnection创建连接,并返回Connection的Observable属性(从createConnection返回).在最简单的(简化)视图中,它看起来像这样

class XHRConnection implements Connection {
  response: Observable<Response>;
  constructor( request,browserXhr) {
    this.response = new Observable((observer: Observer<Response>) => {
      let xhr = browserXhr.create();
      let onLoad = (..) => {
        observer.next(new Response(...));
      };
      xhr.addEventListener('load',onLoad);
    })
  }
}

class XHRBACkend implements ConnectionBACkend {
  constructor(private browserXhr) {}
  createConnection(request): XHRConnection {
    return new XHRConnection(request,this.broswerXhr).response;
  }
}

class http {
  constructor(private BACkend: ConnectionBACkend) {}

  get(url,options): Observable<Response> {
    return this.BACkend.createConnection(createrequest(url,options)).response;
  }
}

因此,了解这种架构,我们可以尝试实现类似的东西.

对于Connection,这是POC.为简洁而省略了导入,但在大多数情况下,所有内容都可以从@ angular / http导入,Observable / Observer可以从rxjs / {TypE}导入.

export class Chunk {
  data: String;
}

export class ChunkedXHRConnection implements Connection {
  request: request;
  response: Observable<Response>;
  readyState: ReadyState;

  chunks: Observable<Chunk>;

  constructor(req: request,browserXHR: BrowserXhr,baseResponSEOptions?: ResponSEOptions) {
    this.request = req;
    this.chunks = new Observable<Chunk>((chunkObserver: Observer<Chunk>) => {
      let _xhr: XMLhttprequest = browserXHR.build();
      let prevIoUsLen = 0;
      let onProgress = (progress: ProgressEvent) => {
        let text = _xhr.responseText;
        text = text.subString(prevIoUsLen);
        chunkObserver.next({ data: text });
        prevIoUsLen += text.length;

        console.log(`chunk data: ${text}`);
      };
      _xhr.addEventListener('progress',onProgress);
      _xhr.open(requestMethod[req.method].toUpperCase(),req.url);
      _xhr.send(this.request.getBody());
      return () => {
        _xhr.removeEventListener('progress',onProgress);
        _xhr.abort();
      };
    });
  }
}

这是我们刚订阅XHR进展事件.由于XHR.responseText会发出整个连接文本,我们只需子串获取块,然后通过Observer发出每个chuck.

对于XHRBACkend,我们有以下(没什么了不起的).同样,一切都可以从@ angular / http导入;

@Injectable()
export class ChunkedXHRBACkend implements ConnectionBACkend {
  constructor(
      private _browserXHR: BrowserXhr,private _baseResponSEOptions: ResponSEOptions,private _xsrfStrategy: XSRFStrategy) {}

  createConnection(request: request): ChunkedXHRConnection {
    this._xsrfStrategy.configurerequest(request);
    return new ChunkedXHRConnection(request,this._browserXHR,this._baseResponSEOptions);
  }
}

对于http,我们将扩展它,添加一个getChunks方法.如果需要,您可以添加更多方法.

@Injectable()
export class Chunkedhttp extends http {
  constructor(protected BACkend: ChunkedXHRBACkend,protected defaultOptions: requestOptions) {
    super(BACkend,defaultOptions);
  }

  getChunks(url,options?: requestOptionsArgs): Observable<Chunk> {
    return this.BACkend.createConnection(
       new request(mergeOptions(this.defaultOptions,options,requestMethod.Get,url))).chunks;
  }
}
@H_529_5@mergeOptions方法可以在Http source中找到.

现在我们可以为它创建一个模块.用户应该直接使用Chunkedhttp而不是http.但是因为不试图覆盖http令牌,如果需要,你仍然可以使用http.

@NgModule({
  imports: [ httpR_988_11845@odule ],providers: [
    {
      provide: Chunkedhttp,useFactory: (BACkend: ChunkedXHRBACkend,options: requestOptions) => {
        return new Chunkedhttp(BACkend,options);
      },deps: [ ChunkedXHRBACkend,requestOptions ]
    },ChunkedXHRBACkend
  ]
})
export class ChunkedhttpR_988_11845@odule {
}

我们导入httpR_988_11845@odule,因为它提供了我们需要注入的其他服务,但是如果我们不需要,我们不希望重新实现这些服务.

要测试只是将ChunkedhttpR_988_11845@odule导入AppModule.另外要测试我使用了以下组件

@Component({
  SELEctor: 'app',encapsulation: ViewEncapsulation.None,template: `
    <button (click)="onClick()">Click Me!</button>
    <h4 *ngFor="let chunk of chunks">{{ chunk }}</h4>
  `,styleUrls: ['./app.style.css']
})
export class App {
  chunks: String[] = [];

  constructor(private http: Chunkedhttp) {}

  onClick() {
    this.http.getChunks('http://localhost:8080/api/resource')
      .subscribe(chunk => this.chunks.push(chunk.data));
  }
}

我有一个后端端点设置,它每隔半秒就会在10个块中吐出“消息#x”.这就是结果

使用Angular2 / RxJS读取缓冲响应

某处似乎有一个bug.只有九个:-).我认为它与服务器端有关.

大佬总结

以上是大佬教程为你收集整理的使用Angular2 / RxJS读取缓冲响应全部内容,希望文章能够帮你解决使用Angular2 / RxJS读取缓冲响应所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。