简体   繁体   English

promise 链的问题

[英]Issue with promise chain

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));
    });
}

I am not able to figure out why in above code the execution does not move to second then block.我无法弄清楚为什么在上面的代码中执行没有移动到第二个然后阻塞。 The browser console logs is as follows.浏览器控制台日志如下。

在此处输入图像描述

However if i remove the line console.log(response.json());但是,如果我删除行console.log(response.json()); , the code works fine. ,代码工作正常。 May be it is a very basic question, but somehow i am not able to figure out.可能这是一个非常基本的问题,但不知何故我无法弄清楚。 If you know, please help me.如果你知道,请帮助我。 Thanks in advance.提前致谢。

在此处输入图像描述

The Response#body is aReadableStream . Response#bodyReadableStream A stream can be consumed only once and then It's empty.一个 stream 只能消耗一次然后就空了。 Since the Body#json() method reads the stream to completion , the second time you try to use the same body, you are tapping into an empty stream.由于Body#json()方法将 stream 读取到完成,因此您第二次尝试使用相同的主体时,您正在利用一个空的 stream。 That's why the Response API implementation locks the stream and doesn't allow to call the method twice.这就是为什么Response API 实现锁定 stream 并且不允许调用该方法两次。

You can try It yourself:你可以自己试试:

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

Calling response.json() locks the resouce so the second call will fail.调用response.json()会锁定资源,因此第二次调用将失败。

You should avoid calling it twice but if you really want to see the result there I would advice you using this code:您应该避免调用它两次,但如果您真的想在那里看到结果,我建议您使用以下代码:

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

or simply log it in the second then :或者干脆将其登录到第二个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();
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM