Javascript 有没有一种方法可以只使用一个回调递归地进行异步调用?

Javascript 有没有一种方法可以只使用一个回调递归地进行异步调用?,javascript,express,asynchronous,recursion,cloudant,Javascript,Express,Asynchronous,Recursion,Cloudant,我想知道是否有人知道在javascript中递归执行异步调用的方法。我试图将批量数据一次上传500个项目到cloudant数据库。我不知道json会有多少文档长(大约在2000-4000之间),所以我创建了一个递归函数,将它分成500个块并上传 insertDBBulkData: function(trgtDB, dbDocData, callback) { // if length > 500, recursively upload 500 at a time if(d

我想知道是否有人知道在javascript中递归执行异步调用的方法。我试图将批量数据一次上传500个项目到cloudant数据库。我不知道json会有多少文档长(大约在2000-4000之间),所以我创建了一个递归函数,将它分成500个块并上传

insertDBBulkData: function(trgtDB, dbDocData, callback) {

    // if length > 500, recursively upload 500 at a time
    if(dbDocData.length > 500) {
        console.log("File too big. Length " + dbDocData.length)
        module.exports.insertDBBulkData(trgtDB, dbDocData.slice(500, dbDocData.length), function(err, body) {
            if(err) {   
                console.log(err);
                callback(err, body)
            } else {
                // only callback on last one
                callback(err, body);
            }
        });

        dbDocData = dbDocData.slice(0, 500);
    }

    trgtDB.bulk({"docs": dbDocData}, function(err, body) {
        if(err) {
            callback(err);
        } else {
            console.log("Successfully uploaded " + dbDocData.length + " users. ")
            callback(null, "Success!")
        }
    });
},
问题是:因为我不知道哪个调用将最后完成,所以我不知道何时将响应发送回服务器(我只能执行一次)。我已经尝试过使用承诺,但据我所知,我不能将承诺用于这个递归方法,因为我没有固定的方法调用次数。这是可以通过延迟承诺实现的吗

感谢您的帮助。 谢谢

解决方案: 多亏了Jonas W.我能够在for循环中实现多个承诺。它不使用递归,但工作得更好。以下是我的解决方案:

insertDBBulkData: function(trgtDB, dbDocData, callback) {
    const promises = [];

    for(let start = 0; start < dbDocData.length; start += 500) {
        console.log("File too big. Index: " + start);

        var dbBulkDataPromise = new Promise(function(resolve, reject) {
            trgtDB.bulk({"docs": dbDocData.slice(start, start+500)}, function(err, body) {
                if(err) {
                    reject(err);
                } else {
                    resolve("Success")
                }
            });
        });

        promises.push(dbBulkDataPromise);
    }

    Promise.all(promises).then(function(values) {
        console.log(values);
        var completed = true;

        for (message in values) {
            if (message != "Success") {
                completed = false;
            }
        }

        if (completed) {
            callback(null, values)
        } else {
            console.log("Partial upload")
            callback("Partial upload only", null)
        }


    }).catch(function(err) {
        console.log("Error uploading data: " + err);
        callback(err, null)
    });
},
insertDBBulkData:function(trgtDB、dbDocData、回调){
常量承诺=[];
对于(让start=0;start
下面是一个使用承诺的快速示例:

const promises = [], size = 500;

for(let start = 0; start < dbDocData.length; start += size)
  promises.push(insert( dbDocData.slice(start, start + size) ));

Promise.all(promises).then(() => {
  console.log("all done");
}).catch(/* handle errors */);
函数insertData(trgtDB、dbDocData、回调){
var batchSize=500;
而(dbDocData.length>0){
var batch=dbDocData.slice(0,batchSize);
dbDocData.splice(0,batchSize);
insertBatch(targetDB,dbDocData.slice(500,dbDocData.length))
.然后(函数(结果){
//一切都很好
if(dbDocData.length<1){
回调(yourParams);
}
})
.error(函数(err){
//处理你的错误
});
}
}
函数insertBatch(trgtBD,batch){
//回报新的承诺
返回新承诺(功能(解决、拒绝){
//加载到数据库中
trgtDB.bulk({
“文件”:批处理
},函数(错误,正文){
如果(错误){
//拒绝承诺是错误的
拒绝(错误);
}否则{
//一切都很好,
决心(“成功!”)
}
});
})

}
如果将一个批量插入包装为承诺:

function insert(docs) {
   return new Promise((resolve, reject) => {
      trgtDB.bulk({ docs }, function(err, body) {
        if(err) {
          reject(err);
        } else {
           console.log("Successfully uploaded " + docs.length + " users. ")
           resolve("Success!")
       }
   });
  });
}
现在,您可以查看大批量数据,将其切成块,开始插入每个块,然后等待所有承诺:

const promises = [], size = 500;

for(let start = 0; start < dbDocData.length; start += size)
  promises.push(insert( dbDocData.slice(start, start + size) ));

Promise.all(promises).then(() => {
  console.log("all done");
}).catch(/* handle errors */);
const promises=[],size=500;
for(让start=0;start{
控制台日志(“全部完成”);
}).catch(/*处理错误*/);

您正在并行地将所有内容插入数据库,只是在不同的块中。这真的是你不想做的吗?还是您计划一个接一个地执行此操作?所有内容都可以并行插入,因为我稍后会对其进行查询以对其进行排序。那么为什么要将其拆分为多个调用?一个cloudant db调用用于所有数据太大,无法一次发送。这给了我一个错误。你能发送一组数据的总计数和收到的更新计数吗?这太棒了!工作完美。我将用我的完整解决方案更新问题。