【问题标题】:Nodejs - Need to perform around 100 API Async requestNodejs - 需要执行大约 100 个 API 异步请求
【发布时间】:2021-03-03 14:58:14
【问题描述】:

我是 nodejs 的新手,我尝试通过在单个请求中使用 axios npm 来执行大约 100 个 API 请求。以更好的性能/错误跟踪方式捕获所有响应的最佳代码逻辑是什么。

需要在单个 JSON 文件中捕获所有响应,所以我决定使用 createWriteStream('filename.json') 以避免内存问题。

我试过了

const axios = require('axios');
const fs = require('fs');
const config = require('./config/secret.json');

app.get('/json', (req,res) => {

    const linkArr = ['https://apirequest1.com','https://apirequest2.com','https://apirequest3.com','https://apirequest4.com', '...'];
    const wipArr = [];

    for(let getAPI of linkArr){
        axios({
            method: 'get',
            url: getAPI,
            auth: {username: config.username, password: config.secret}
        })
        .then(function (response){
            const writeStream = fs.createWriteStream('wip.json');
            writeStream.write(JSON.stringify(response.data));
        })
        .catch(function (error){
            console.log(error);
        })
    }
    res.send('successfully saved all response');
});

单次捕获所有API响应并在完成API请求后将它们保存在数组中,需要将所有响应写入JSON文件。

提前致谢!

【问题讨论】:

  • response.data 是否显示了什么?我认为 axios 需要 data 仅用于发布
  • @Ifaruki 是的,我收到了 API 响应,我们有 data 关键字作为响应。

标签: node.js async-await axios createwritestream


【解决方案1】:

您遇到的第一个问题是每次都创建流。这将在每次解决承诺时覆盖内容。删除此行。

const writeStream = fs.createWriteStream('wip.json');

你会有这样的东西。

const axios = require('axios');
const fs = require('fs');
const config = require('./config/secret.json');
const writeStream = fs.createWriteStream('wip.json');

app.get('/json', (req,res) => {


    const linkArr = ['https://apirequest1.com','https://apirequest2.com','https://apirequest3.com','https://apirequest4.com', '...'];
    const wipArr = [];

    for(let getAPI of linkArr){
        axios({
            method: 'get',
            url: getAPI,
            auth: {username: config.username, password: config.secret}
        })
        .then(function (response){
            //const writeStream = fs.createWriteStream('wip.json'); // remove this line because it will overwrite the file for each response.
            writeStream.write(JSON.stringify(response.data));
        })
        .catch(function (error){
            console.log(error);
        })
    }
    res.send('successfully saved all response');
})

;

编辑:要等待所有请求,您可以尝试这样的操作。

app.get('/json', async (req, res) => {
    let resp = null;
    const writeStream = fs.createWriteStream('wip.json');
    const linkArr = ['https://apirequest1.com', 'https://apirequest2.com', 'https://apirequest3.com', 'https://apirequest4.com', '...'];
    const promises = [];
    for (let getAPI of linkArr) {
        promises.push(makeCall(getAPI));
        resp = await Promise.all(promises); // resp is array of responses

       // for (let i = 0; i < resp.length; i++) {
          //  writeStream.write(JSON.stringify(resp[i], null, 4)); // to //format the json string
      //  }
    }
 for (let i = 0; i < resp.length; i++) {
                writeStream.write(JSON.stringify(resp[i], null, 4)); // to format the json string
            }
    res.send('successfully saved all response');
});


function makeCall(getAPI) {
    axios({
            method: 'get',
            url: getAPI,
            auth: { username: config.username, password: config.secret }
        })
        .then(function(response) {
            return response.data;
        });
}

我没有测试过它,但是类似的东西。这将运行所有请求。

您可以使用格式化 JSON 字符串。

JSON.stringify(resp[i], null, 4).

看看https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify

编辑:问题在于writeStream.write(JSON.stringify(resp[i], null, 4)); 在循环内。把它移到外面。

添加的代码未经测试。这应该适合你。

app.get('/json', async(req, res) => {
    const writeStream = fs.createWriteStream('wip.json');
    const linkArr = ['https://apirequest1.com', 'https://apirequest2.com', 'https://apirequest3.com', 'https://apirequest4.com', '...'];
    const promises = [];
    for (let getAPI of linkArr) {
        promises.push(makeCall(getAPI));
    }
    const resp = await Promise.all(promises); // resp is array of responses
    for (let i = 0; i < resp.length; i++) {
        writeStream.write(JSON.stringify(resp[i], null, 4)); // to format the json string
    }
    res.send('successfully saved all response');
});



 function makeCall(getAPI) {
    return axios({
        method: 'get',
        url: getAPI,
        auth: { username: config.username, password: config.secret }
    })
    }

【讨论】:

  • 感谢您的回复,我可以将回复保存在 JSON 文件中。在 JSON 文件中保存每个请求后。面对 JSON 格式化程序问题,我还需要在完成 100 个请求过程后向客户端发送响应。
  • @Anand,有帮助吗?
  • 出现以下错误(节点:14396) UnhandledPromiseRejectionWarning:TypeError [ERR_INVALID_ARG_TYPE]:“块”参数必须是字符串类型或 Buffer 或 Uint8Array 的实例。在 processTicksAndRejections (internal/process/task_queues.js:93:5) 的 C:\Users\ranand20\myapp\app.js:105:29 在 WriteStream.Writable.write (_stream_writable.js:285:13) 处收到 undefined /跨度>
  • writeStreamFile.write(JSON.stringify(resp[i], null, 4));此行抛出错误
  • 您的回复有问题。它可能不是有效的 JSON。你能在输出失败之前发布输出吗?
猜你喜欢
  • 2011-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-04
  • 1970-01-01
  • 2022-01-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多