簡體   English   中英

多個 api 調用的正確方法是什么?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM