[英]What is the right way for multiple api call?
我正在做一個項目,通過 axios 調用更新許多患者的信息。 我將患者的 csv 文件解析為 JSON 格式。 並且,請致電 api 來更新每位患者的信息,如下所示。
/**
* this.csvJson.data : List of JSON format, each json contain one patient's information
*/
.
.
await this.csvJson.data.map(async (data)=>{
await axios.post(`api/MetaData/${this.projects.projectId}`,data)
.then(response=>{
//response handling
})
.catch(error=>{
//error handling
})
})
.
.
在這種情況下,當患者人數在200人以下時,上傳過程比較穩定。 但是當患者數量超過 20000 時,瀏覽器沒有響應。 我認為為每個患者調用多個 api 會導致瀏覽器崩潰。
像這樣處理多個 api 調用的正確方法是什么?
對於使用 Promise.all 的多個 apiCall 通常是更好的選擇,但我不知道它是否可以處理 20 000 個請求
const promises = csvJsonData.map((patientData) => {
return axios.post(`api/MetaData/${this.projects.projectId}`, data);
});
Promise.all(promises)
.then((response) => {
//response handling
})
.catch((error) => {
//error handling
});
使用該代碼,您會立即發出 20000 個請求,難怪瀏覽器會崩潰。 由於您已經在使用外部庫,因此可以查看fastq 。
這是我在 React 中的實現,基本上 fastq 可以獲取每個請求的每個參數,然后將每個參數包裝在一個異步工作者 function 中,然后它一次只會執行“並發”數量的請求。 如果您根據請求的速度發出 20000 個請求,則需要時間才能完成。 您可能希望添加更多並發性以使其更快。
import fastq from "fastq";
export async function consecutiveRequest(data, requester, concurrency = 10) {
const workerFunction= async (args) => {
try {
const data = await requester(args.params);
console.log(args.index, "Requested:", args, "Result:", data);
return data;
} catch (error) {
console.error(error);
return null;
}
};
const consecutiveQueue = fastq.promise(
workerFunction, // fastq take a worker function
concurrency // number of requests only allowed at a time
);
const req = [];
for (let i = 0; i < data.length; i++) {
const params = data[i];
req.push(consecutiveQueue.push({ params, index: i }));
}
let data = await Promise.all(req);
return data;
}
import _ from "lodash";
import React from "react";
import { consecutiveRequest } from "./request";
import "./styles.css";
export default function App() {
const randomNumbers = _.range(0, 50).map(() => _.random(0, 4));
const [results, setResults] = React.useState([]);
const [loading, setLoading] = React.useState(false);
const handleSendQueueRequest = async () => {
setLoading(true);
const res = await consecutiveRequest(
randomNumbers,
async (random) => {
const url = `https://cat-fact.herokuapp.com/facts`;
const res = await fetch(url, { method: "GET" });
const json = await res.json();
const facts = json || [];
return facts[random]?.text;
},
10
);
setResults(res);
setLoading(false);
};
return (
<div className="App">
<button disabled={loading} onClick={handleSendQueueRequest}>
{loading ? "Loading" : "Get Random Quote"}
</button>
<pre>{JSON.stringify(results, null, 2)}</pre>
</div>
);
}
下面是代碼框,在控制台中查看它的工作原理。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.