Is angular really following the fetch's specif

2019-07-29 02:05发布

问题:

The Angular's http docs says that the response returned by the http service follows the fetch specification.

https://angular.io/guide/http#parse-to-json

And in their example, this is the code you can find

private extractData(res: Response) {
  let body = res.json();
  return body.data || { };
}

In which, obviously, the result of res.json() is not a promise.

But in the fetch specification, the response.json() method is supposed to return a Promise.

https://fetch.spec.whatwg.org/#response-class

Am I missing something in the fetch spec or is Angular wrong about it's implementation?

回答1:

Looking into angular's http source it's clear it doesn't return a Promise:

 json(): any {
    if (typeof this._body === 'string') {
      return JSON.parse(<string>this._body);
    }

    if (this._body instanceof ArrayBuffer) {
      return JSON.parse(this.text());
    }

    return this._body;
  }

  // source https://github.com/angular/angular/blob/master/packages/http/src/body.ts#L26

But the spec says

[NoInterfaceObject, Exposed=(Window,Worker)]
interface Body {
  readonly attribute ReadableStream? body;
  readonly attribute boolean bodyUsed;
  [NewObject] Promise<ArrayBuffer> arrayBuffer();
  [NewObject] Promise<Blob> blob();
  [NewObject] Promise<FormData> formData();
  [NewObject] Promise<any> json();
  [NewObject] Promise<USVString> text();
};

So it seems that angular decided not to follow the spec strictly.



回答2:

I think you're right (because of consume body algo), they aren't following the spec for fetch, internally they are using JSON.parse to parse the JSON (see: github).

I think they're doing it to propagate the error more easily up the callstack, so the user can easily catch it himself via http.get().catch(). But for more information try to ask them directly via gitter.