我正在使用async.js系列进行连续的http get调用,所有这些都在for循环内。首先,我从API查询中检索了许多结果,然后对每个结果运行另一个查询。结果存储在数组中,然后保存到CouchDB数据库。因为结果的数量限制为200,所以我必须多次执行此操作(因此for循环)。该代码的基本结构如下(下面是完整代码)
for (...) {
async.series(
[
function(){ http get method },
function (){ async.eachSeries(){ http get method }, callback function }
],
function(){ database operations }
);//end series
}//end for loop
我的问题是循环仅执行一次。循环中的所有内容均按预期工作,并且数据已正确保存到数据库中-但我不知道为什么循环不会再次运行。我知道如果在异步回调函数中放置方法调用,它将运行良好,所以也许我缺少有关异步工作原理的信息。我认为for循环应该在调用堆栈上,所以当异步完成后,循环应该继续下去,但是显然不是这样。
完整代码:
for (var retstart = 0; retstart < elsvr_count; retstart += elsvr_retSize) {
var elsvr_resultChunk;
async.series(
[
function(callback){
var elsvr_Query = String(elsvr_baseURL) + "apiKey="+ String(elsvr_apiKey) + "&query=af-id(" + String(elsvr_ID) + ")&httpAccept=application/" + String(elsvr_resultType) + "&count=" + String(elsvr_retSize) + "&view=";
$.get(elsvr_Query, function(result) {
elsvr_count = parseInt(result["search-results"]["opensearch:totalResults"]); //the number of results
console.log("count set at " + elsvr_count);
elsvr_resultChunk = result["search-results"]["entry"]; //the current chunk of the total result, the size of which elsvr_retSize
callback(null);
});//end get
},
function(callback){
async.eachSeries(elsvr_resultChunk, function(item, callback){
var docQuery = item["prism:url"] + "?apiKey=" + String(elsvr_apiKey) + "&httpAccept=application/" + String(elsvr_resultType);
$.ajax({
url: docQuery,
type: 'GET',
dataType: 'json',
success: function(result){
elsvr_results.push(result);
return callback(null);
},
error: function(err){
console.log("error returned: "+err.statusText);
elsvr_errors = elsvr_errors+1;
return callback(null);
}
});
},
function(err, results) {
if (err) console.log("error: " + err);
else
callback(null, elsvr_results);
});
}
],
//callback from async.series
function (err, results){
if (err)
console.log("ERROR: " + JSON.stringify(err));
else {
db.getDoc('unprocessed', function(er, doc){
if (er) throw new Error(JSON.stringify(er));
if (doc.elsvr != undefined)
doc.elsvr = _.extend(results[1], doc.elsvr);
else
doc.elsvr = results[1];
db.saveDoc('unprocessed', doc, function(er, ok) {
if (er) throw new Error(JSON.stringify(er));
console.log('saved a chunk to the database: ' + db.name);
});
});
}
}
);//end async.series
}//end for loop
好的,我终于解决了。事实证明,循环不是同步执行的,并且由于我在异步系列中更新了循环条件(elsvr_count),因此在实际设置条件之前,循环已完成。但是,这不是唯一的问题-如果我删除了该条件更新,并简单地将elsvr_count设置为循环外的一个高数字,则该循环仍会在异步系列返回之前异步运行。
我将发布我的解决方案,以防其他人遇到类似的问题:基本上,如下所示,用async.whilst循环替换for循环
async.whilst(function() { return retstart < elsvr_count; },
function(callback) {
var elsvr_resultChunk;
async.series(
//...
//same stuff as above goes here
//...
//save the document to the database
db.saveDoc('unprocessed', doc, function(er, ok) {
if (er) throw new Error(JSON.stringify(er));
retstart += elsvr_retSize; //<-- to replace the increment of the for loop
callback(null); //<-- important
});
//...
//...
);//end async.series
},
//callback for the whilst loop. this will be called once the condition is no longer met (retstart < elsvr_retSize)
function(err) {
//do stuff in here
}
);//end async.whilst
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句