Async.jsシリーズ内のGETメソッドとCouchDB操作が複数回以上実行されていないループの場合
-
23-12-2019 - |
質問
async.jsシリーズを使用して連続してhttpを取得しています。まず、APIクエリからの数の結果を検索してから、各結果について別のクエリを実行します。結果は配列に格納され、次にCouchDBデータベースに保存されます。結果の数は200に制限されているので、私はこれを複数回実行する必要があります(したがって、for Loop)。コードの基本構造は以下の通りです(下記のフルコード)
for (...) {
async.series(
[
function(){ http get method },
function (){ async.eachSeries(){ http get method }, callback function }
],
function(){ database operations }
);//end series
}//end for loop
.
私の問題は、ループが一度だけ実行されることです。ループ内のすべてが予想どおりに機能し、データはデータベースに正しく保存されます。ただし、ループが再度実行されない理由を理解できません。私は私がAsyncコールバック関数でメソッド呼び出しをするかどうかを知っています。For Loopはコールスタックにあるはずだと思います。したがって、非同期が行われると、ループは単に続行する必要がありますが、これは明らかにそうではありません。
フルコード:
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
. 解決
大丈夫、私はついにそれを解決しました。ループが同期的に実行されていないことが判明したため、ASYNCシリーズ内部のループ条件付き(ELSVR_COUNT)を更新するため、条件付きが正しく設定される前にループが終了しました。ただし、それは唯一の問題ではありませんでした - その条件付きアップデートを削除し、単にelsvr_countをループの外側の多数の数に設定すると、ASYNCシリーズが返される前にループは非同期的に実行されます。
他の人が同様の問題に遭遇した場合に私の解決策を投稿します。基本的にはforループを非同期に置き換えます.Whilstループ
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
. 所属していません StackOverflow