节点:请求内部的请求内部循环



我有下面的代码,它请求返回之前所有计划的消息,如果有,它会用新的日期更新"计划"集合中的每个文档(根据重复字段增加其值(,如果完成了此文档更新,它会在"消息"集合上插入一个新文档。

问题是我做了一个过于复杂的代码,它在最后插入了重复的消息。我怀疑函数"insertScheduledMsgs"在更新循环中的"scheduled"文档的异步请求完成之前被再次调用,所以下次调用该函数时,日程文档仍然有旧日期。

我该如何做得更简单并解决这个问题?

下面你可以看到整个代码:

function insertScheduledMsgs() {
request.get( {
headers: { 'Authorization':'Bearer ' + token },
url: urlApi + "scheduleBeforeOrAfterNow?msgsPosition=before"
}, function( error, response, body ){
if ( !error && response.statusCode == 200 ) {
results = JSON.parse( body );
for ( let res in results ){
let bodyMsg = "",
bodySchedule = "",
log,
scheduleDate = (Number( results[res].date ) + ( Number( results[res].repeat ) * 60 * 1000)),
date1 = new Date(results[res].date),
date2 = new Date();
bodyMsg += 'user=' + results[res].user;
if ( results[res].media ) {
bodyMsg += '&media=' + results[res].media;
}
bodyMsg += '&txt=' + results[res].txt;
bodyMsg += '&time=' + results[res].time;
bodyMsg += '&layout=' + results[res].layout;
bodyMsg += '&boxes=' + results[res].boxes;
bodySchedule += '_id=' + results[res]._id;
bodySchedule += '&date=' + scheduleDate;
if( date1.setSeconds(0,0) <=  date2.setSeconds(0,0) ) {
request.put( {
headers: { 'content-type' : 'application/x-www-form-urlencoded', 'Authorization':'Bearer ' + token },
url: urlApi + "schedule",
body: bodySchedule
}, function( errorSchedule, responseSchedule, body ){
logs({
event: "date updated in scheduled msg",
date: new Date().getTime()
}, token);
if( date1.setSeconds(0,0) ===  date2.setSeconds(0,0) ) {
request.post( {
headers: { 'content-type' : 'application/x-www-form-urlencoded', 'Authorization':'Bearer ' + token },
url: urlApi + "msgs",
body: bodyMsg
}, function( errorMsg, responseMsg, body ){
logs({
event: "scheduled msg sent to monitor / tv",
date: new Date().getTime()
}, token);
if ( (Number(res) + 1) === results.length ) {
insertScheduledMsgs();
}
} );
} else {
if ( (Number(res) + 1) === results.length ) {
insertScheduledMsgs();
}
}                   
} );
} else {
if ( (Number(res) + 1) === results.length ) {
insertScheduledMsgs();
}
}
};
} else {
insertScheduledMsgs();
}
} );

};

可能是for循环中的某个值更新过快,导致该值在异步任务之间发生了更改。如果是这种情况,您可以尝试将使用这些值的代码包装到立即调用的函数表达式(IIFE(中,以便将这些值保存在内部。请参阅下面的两个示例:异步任务是用超时来模拟的。如果没有IIFE,所有执行都显示最后一个值,因为循环在运行时已经完成。使用IIFE时,值将保持为达到代码时的状态。在您的情况下,date1可能是有罪的,但res可能也是有罪的(注意,您必须在异步成功中进行日志记录才能看到问题(:

var arr = [{val: 'test1'}, {val: 'test2'}, {val: 'test3'}],
i, l = arr.length, value;
for(i = 0; i < l; i++){

value = arr[i];

console.log('LOOPING i / value: ', i, value);

setTimeout(function(){
console.log('WITHOUT IIFE WRAP i / value: ', i, value);
}, 1);

(function(_i, _value){
setTimeout(function(){
console.log('WITH IIFE WRAP i / value: ', _i, _value);
}, 1);
})(i, value);

}

最新更新