Проблема с цепочкой обещаний - PullRequest
2 голосов
/ 15 апреля 2020
import { Observable } from 'rxjs/internal/Observable';

export function createHttpObservable(url: string) {
    console.log('Url is', url);
    return Observable.create(observer => {
        fetch(url)
        .then(response => {
            console.log(response);
            console.log(response.json());
            return response.json();
        })
        .then(body => {
            observer.next(body);
            observer.complete();
        })
        .catch(err => observer.error(err));
    });
}

Я не могу понять, почему в приведенном выше коде выполнение не перемещается на второй, а затем на блок. Журналы консоли браузера выглядят следующим образом.

enter image description here

Однако, если я удалю строку console.log (response. json ()) ; , код работает нормально. Может быть, это очень простой вопрос, но почему-то я не могу понять. Если вы знаете, пожалуйста, помогите мне. Заранее спасибо.

enter image description here

Ответы [ 2 ]

1 голос
/ 15 апреля 2020

Response#body - это ReadableStream. Поток можно использовать только один раз, а затем он пуст. Поскольку метод Body#json() читает поток до завершения , во второй раз, когда вы пытаетесь использовать то же тело, вы подключаетесь к пустому потоку. Вот почему реализация Response API блокирует поток и не позволяет дважды вызывать метод.

Вы можете попробовать сами:

const a = new ReadableStream();
const b = new Response(a);

b.json(); // returns a Promise
b.json(); // TypeError: Failed to execute 'json' on 'Response': body stream is locked
0 голосов
/ 15 апреля 2020

Вызов response.json() блокирует ресурс, поэтому второй вызов не будет выполнен.

Вам следует избегать его повторного вызова , но если вы действительно хотите увидеть результат, я бы посоветовал вам использовать этот код:

   required here
       \/
.then(async response => {
    console.log(response);
    console.log(await response.clone().json()); // read json result from cloned response
    return response.json();
})

или просто войдите во второй then:

.then(async response => {
   console.log(response);
   return response.json();
 })
.then(body => { 
   console.log(body); // it doesn't require any workarounds
   observer.next(body);
   observer.complete();
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...