首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >嵌套的for循环结合了Nodejs中的API获取数据?

嵌套的for循环结合了Nodejs中的API获取数据?
EN

Stack Overflow用户
提问于 2018-12-04 02:31:42
回答 5查看 1.2K关注 0票数 1

我的场景如下:有一个我想要获取的API。API返回一个json,该json有一个名为"assets“的数组。该数组大小始终为20。现在,我这样调用端点:

代码语言:javascript
复制
 fetch(
     `https://api.example.io/api/v1/assets/?offset=${offset}`
 )

其中,如果offset为0,则返回0- 20资产的数组,如果offset为20,则返回20到40,依此类推。

我想检查1000个项目,这意味着我想调用这个fetch 1000/20 = 50次。每当我调用fetch时,我都会循环这20个项目,并将它们插入到我的数据库中。问题是我不能做这样的事情:

代码语言:javascript
复制
let offset=0;

for(let i = 0; i < 50; i++ {
    fetch(
       `https://api.example.io/api/v1/assets/?offset=${offset}`
    )
    for(let j = 0; j < 20; j++){
    // Insert into DB
    }
    offset+=20;
}

由于JS的异步特性。每当我尝试这样做时,它都会多次调用fetch,偏移量的值为0,它不会等到嵌套的for循环完成,然后调用20或更晚的40,依此类推……

实现这一行为的正确方法是什么?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2018-12-04 02:53:57

我从我的一个nodeJS代码库中删除了以下代码,因为它使用异步代码来解决非常类似的问题:

代码语言:javascript
复制
// Throttling is important because you don't want to
// overload the API
const createThrottle = require('async-throttle');
const throttle = createThrottle(2);

// First push all the links into an array using
// the offset
const links = [];
for (let offset = 0; offset < 100; offset += 20) {
  links.push(`https://api.example.io/api/v1/assets/?offset=${offset}`);
}

// Next create an array of promises by `map`ing
// over the links using `fetch`.
// Notice I've used throttle here to slow down the hits on
// the API
const promises = links.map(link => throttle(async => () {
  const res = await fetch(link);
  return await res.json();
}));

// Once all the promises are complete, iterate over their datasets
Promise.all(promises).then(datasets => {
  // iterate over datasets
});
票数 0
EN

Stack Overflow用户

发布于 2018-12-04 02:44:01

您可以使用递归或Promises来代替for..loop。

递归::

代码语言:javascript
复制
let insertToDB = function (records, cb) {
  if (!records.length) return cb();
  let record = records.shift();//assuming records is an array
  // Insert record into DB1
  insertToDB(records, cb);
};

let loop = function (count, offset, cb) {
 if (!count) return cb();
 fetch(
    `https://api.example.io/api/v1/assets/?offset=${offset}`
 )
 insertToDB(recordsFromFetch, function () {
    offset += 20;
    --count;
    loop(count, offset, cb)
 })
};


loop(50, 0, function () {
  console.log("All Done");
})

Promise::我还没有运行它,所以可能有一些语法错误,但是您应该明白了

代码语言:javascript
复制
let insertToDB = function (record) {
    return new Promise(function (resolve, reject) {
    // Insert record into DB then call resolve
    resolve();
    })
};

let fetchPhase = function (offset) {
    fetch(
    `https://api.example.io/api/v1/assets/?offset=${offset}`
   )
    let dbAll = [];
   for (let j = 0; j < 20; j++) {
    // assuming you get records from fetch , pass record to be added to db in the parameter
    dbAll.push(insertToDB(records[j]))
}
 return Promise.all(dbAll)
};

let all = [];

let offset = 0;

for (let i = 0; i < 50; i++) {
    all.push(fetchPhase(i));
}

Promise.all(all)
.then(function () {
    console.log("ALL DONe");
})
票数 0
EN

Stack Overflow用户

发布于 2018-12-04 02:47:55

为什么不使用Promise.all

代码语言:javascript
复制
const promises = [];

for (let i = 0; i < 10; i++) {
    promises.push(
    fetch(`https://api.example.io/api/v1/assets/?offset=${i}`)
  );
}

Promise.all(promises).then( _results => {
    // All fetch calls have completed at this point. _results will be in array of your fetch results.
    console.log(results);
    // Do db insert here

});

你可以做的一件事就是做一个承诺的function。在该函数中,让它执行fetch,然后执行db insert all in one函数(使用.then)。如果您这样做,那么单个Promise.all调用就可以处理所有事情。如果不这样做,您将不得不再次循环promises并将这些值插入到数据库中。它可能看起来像这样:

代码语言:javascript
复制
const promises = [];

for (let i = 0; i < 10; i++) {
    promises.push(fetchAndInsert(i));
}

Promise.all(promises).then( _results => {
    console.log(results);

});


function fetchAndInsert(offset) {
    return new Promise( (resolve, reject) => {
    fetch(`https://api.example.io/api/v1/assets/?offset=${i}`).then (_result => {
        // db.insert().then( _result => {
            //resolve();
      //})
    })
  })
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53599748

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档