NodeJS等待axios + nedb函数async / await运行下一个查询

问题描述

我想在NodeJS脚本中使用Axios + nedb将数据从API收集到本地文件中。这是我到目前为止所做的:

var axios = require('axios');
var Datastore = require('nedb');
const fs = require('fs');

db = new Datastore({ filename: './../smb_share/art.db',autoload: true });

function getArt(limit,offset) {
    var config = {
      method: 'get',url: 'http://IPADD/api/data/2:1/?limit=' + limit + '&offset=' + offset',headers: { 
        'Accept': 'application/simple+json','Content-Type': 'application/json','Authorization': 'Basic XYZ'
      }
    };

    axios(config)
      .then(function (response) {
          response.data.erpDataObjects.forEach(element => {
              var doc = { number:element.head.number,desc:element.head.desc
              };
              db.insert(doc,function (err,newDoc) {
                if(err =! null){
                  console.log(err);
                }   
            });
          });  
      })
    .catch(function (error) {
        console.log(error);
    });  
}

getArt(1000,0)
getArt(1000,1000)

这很好,只要我不从API收集更多数据即可。我需要约400次调用函数“ getArt(limit,offset)”,因为我从API中获取了约400000个文档。我尝试使用intervalTimers来执行此操作,因此每隔5分钟启动一次函数,并在每次触发间隔事件时以++ offset开始1000次...是的,我知道这很奇怪,但这是目前对我有用的唯一方法。但是,当API服务器负载沉重时,一个查询所花的时间太长,而且我超出了通话限制,结果一团糟。

我的问题:当以前的功能准备就绪时,如何使事情保持清楚并启动功能?我尝试了很多异步/等待的东西,但是全部都以错误告终或全部同时被解雇。我基本上需要的是类似...

getArt(10000,0)
.then
getArt(10000,10000)
.then
getArt(10000,20000)
.then
...

但是使用axios的嵌套功能,我不知道如何通过承诺来处理此问题。有人可以给我提示吗?

解决方法

您是否尝试过将getArt设为async function并简单地awaiting制成

async function getArt(limit,offset){...}

async function Name(){
  await getArt(10000,1000); // wait to complete before moving on
  await getArt(10000,2000); // only execute when above is done
}

Name();

通过不分配await的结果,您只需告诉程序等待,以使该功能完成,然后再继续执行下一个。

旁注:

为什么不进行for循环以增加偏移量并调用getArt函数?

async function Name(){
  var limit = 10000;
  for(let offset = 0; offset < limit; offset += limit/10){
    await getArt(limit,offset);
  }
}

Name();

我还没有测试过,但是没有理由不起作用。

另外,(遵循良好实践准则)您应该将await语句包装在try-catch块中,以处理类似这样的错误:

try{
  await getArt(limit,offset);
}
catch(err){
  console.error(err);
}