我有下面的代码,该代码要求现在返回所有预定的消息,如果有的话,它将用新的日期更新“预定”集合中的每个文档(根据重复字段增加其值),如果此文档更新完成,则会在“ msgs”集合上插入一个新文档。
问题是我做了一个过于复杂的代码,并且在末尾插入了重复的味精。我怀疑在循环内更新“计划的”文档的异步请求完成之前,将再次调用函数“ insertScheduledMsgs”,因此,下次调用该函数时,计划的文档仍具有旧日期。
我该如何简化并解决此问题?
下面您可以看到整个代码:
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();
}
} );
};
答案 0 :(得分:0)
也许您的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);
}