简体   繁体   English

无法多次调用 fetch api

[英]Can't call fetch api multiple times

I want to call this api multiple times in my project and when I am calling it, It continues giving an error which is我想在我的项目中多次调用这个 api,当我调用它时,它继续给出一个错误,即

TypeError: Failed to execute 'json' on 'Response': body stream already read at main.js: Line number TypeError:无法在“响应”上执行“json”:主体 stream 已在 main.js 中读取: Line number

My Code is as Follows我的代码如下

let thisIsUrl = 'https://api.covid19api.com/summary';
let a = fetch(thisIsUrl)
a.then((data) => {
    return data.json()
}).then((apidata) => {
    console.log(apidata)
    return apidata
}).catch((error) => {
    console.log(error)
})


a.then((fetchdata) => {
    return fetchdata.json()
}).then((readingData) => {
    console.log(readingData)
}).catch((err) => {
    console.log(err)
})

You're not calling fetch multiple times.不会多次调用fetch You're calling it once , and then trying to read the response body multiple times.您调用它一次,然后尝试多次读取响应正文。 That's why the error says you're trying to read the body when the stream is already closed — it was closed when you were done reading it the first time.这就是为什么当 stream 已经关闭时,错误提示您正在尝试读取正文的原因 - 当您第一次完成读取时它已关闭。

If you want to use the data twice, store it somewhere and use it twice.如果您想使用两次数据,请将其存储在某个地方并使用两次。

let thisIsUrl = 'https://api.covid19api.com/summary';
let a = fetch(thisIsUrl)
a.then((data) => {
    return data.json()
}).then((apidata) => {
    // **************** Use it twice here
}).catch((error) => {
    console.log(error)
})

If you want to fetch it again because it may have been updated, call fetch again:如果您想再次获取它,因为它可能已更新,请再次调用fetch

let thisIsUrl = 'https://api.covid19api.com/summary';
fetch(thisIsUrl)
.then((data) => {
    return data.json();
}).then((apidata) => {
    console.log(apidata);
    return apidata;
}).catch((error) => {
    console.log(error);
});


// Presumably this is later (in time), not immediately after the above
fetch(thisIsUrl)
.then((fetchdata) => {
    return fetchdata.json();
}).then((readingData) => {
    console.log(readingData);
}).catch((err) => {
    console.log(err);
});

Finally, this seems unlikely, but if you really want to fetch it once and use that one result in multiple places via the promise chain, keep the promise from then rather than the promise from fetch :最后,这似乎不太可能,但是如果您真的想获取一次并通过 promise 链在多个地方使用该结果,请then起保留 promise 而不是 promise fetch

let thisIsUrl = 'https://api.covid19api.com/summary';
let a = fetch(thisIsUrl)
.then((data) => {
    return data.json()
});
a.then((apidata) => {
    // ***** Use it here
}).catch((error) => {
    console.log(error)
})

a.then((readingData) => {
    // ***** And then again here
}).catch((err) => {
    console.log(err);
});

Side note: Your code is falling prey to a footgun in the fetch API;旁注:您的代码在fetch API 时成为了猎物; I've written about it in this blog post .我在 这篇博文中写过它。 fetch only rejects its promise on network errors, not HTTP errors. fetch仅在网络错误时拒绝其 promise,而不是 HTTP 错误。 You have to check for those yourself in the first fulfillment handler, by checking for ok on the response object:您必须通过在响应 object 上检查ok来检查第一个履行处理程序中的那些自己:

fetch("/your/resource")
.then(response => {
    if (!response.ok) {
        throw new Error("HTTP error " + response.status); // Or better, use an Error subclass
    }
    return response.json();
})
// ...

fetch returns Promise , generally, promises have something like state inside themself; fetch返回Promise ,一般来说,promise 内部有类似 state 的东西;

  1. pending : initial state, neither fulfilled nor rejected. pending :初始 state,既不履行也不拒绝。
  2. fulfilled : meaning that the operation was completed successfully.fulfilled :表示操作已成功完成。
  3. rejected : meaning that the operation failed. rejected :表示操作失败。

( source ) 来源

So when we call them and get the value from them with then , catch and etc. then they change the state after that call.因此,当我们调用它们并使用thencatch等从它们那里获取值时,它们会在调用之后更改 state。 So here, when you read the value with a.then(… , the promise changes its state to fulfilled and you are not able to call it again, you need a new and fresh Promise, actually a new instance of the fetch .因此,在这里,当您使用a.then(…读取值时,promise 将其 state 更改为已fulfilled并且您无法再次调用它,您需要一个新的和新鲜的fetch实例。

I want to recommend you to use Promise.all().我想推荐你使用 Promise.all()。

let thisIsUrl = 'https://api.covid19api.com/summary';
let a = fetch(thisIsUrl)
.then((data) => {
    return data.json()
}).then((apidata) => {
    console.log(apidata)
    return apidata
}).catch((error) => {
    console.log(error)
})

Promise.all([a,a,a]);
.then(results => {
     // Results are here.
});

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

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