首页 > 解决方案 > 如何将 promise 返回的数据推送到数组中?

问题描述

我正在调用 Udemy API。为了同时拨打电话,我使用了一个循环。通过这样做,我会自动增加页码并尝试从每个页面中获取数据并将其存储到一个数组中,以便我可以将所有数据以 json 格式写入单个文件。但我得到的只是一个空数组。如何访问 promise 返回的值并存储到 doc.table 数组中?

我的代码:

const fetch=require("node-fetch");
const fs=require("fs");
let doc={};
doc.table=[];

for(let i=1;i<=10;i++){

fetch('https://www.udemy.com/api-2.0/courses/ page='+i+'&page_size=10&client_id=${client_id}&client_secret=${client_secret},{
      method:'GET',
      body:null,
      headers:{authorization: ${auth_code}}
      })
      .then(res=>res.json())
      .then(json=>doc.table.push(json))
};


fs.writeFile("UDEMY.json",JSON.stringify(doc),function(err){
    if(err) throw err;
    console.log("Complete");
});

标签: javascriptnode.jsjsones6-promisefetch-api

解决方案


我建议使用await这样您的for循环将在每次迭代时暂停:

const fetch = require("node-fetch");
const fsp = require("fs").promises;

let doc = { table: []};

async function run() {
    for (let i = 1; i <= 10; i++) {

        let data = await fetch(`https://www.udemy.com/api-2.0/courses?page=${i}&page_size=10&client_id=${client_id}&client_secret=${client_secret}`,{
              method:'GET',
              body:null,
              headers:{authorization: auth_code}
        }).then(res=>res.json());

        doc.table.push(data);
    }

    await fsp.writeFile("UDEMY.json",JSON.stringify(doc));
    console.log("done");
}

run().catch(err => {
    console.log(err);
});

另一种可能性是并行运行所有请求并用于Promise.all()知道它们何时全部完成。这两种解决方案的关键是使用fetch()返回控制知道事情何时完成的承诺。

如果你真的想并行运行它们并且你确定你的目标主机会允许它,你可以这样做:

const fetch = require("node-fetch");
const fsp = require("fs").promises;

let doc = { table: []};

function run() {
    let promises = [];
    for (let i = 1; i <= 10; i++) {

        promises.push(fetch(`https://www.udemy.com/api-2.0/courses?page=${i}&page_size=10&client_id=${client_id}&client_secret=${client_secret}`},{
              method:'GET',
              body:null,
              headers:{authorization: ${auth_code}}
        }).then(res=>res.json()));

    }
    return Promise.all(promises).then(data => {
        doc.table = data;
        return fsp.writeFile("UDEMY.json",JSON.stringify(doc));
    });

}

run().then(() => {
    console.log('done');
}).catch(err => {
    console.log(err);
});

而且,如果您想要某种级别的并行请求,但又想限制并行请求的数量,您可以使用这里mapConcurrent()描述的。


推荐阅读