Узел: Запросы внутри запросов Внутри цикла - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть код ниже, который делает запрос на возврат всех запланированных сообщений до этого момента, и если они есть, он обновляет каждый документ в «запланированной» коллекции с новой датой (увеличивая ее значение в соответствии с полем повторения),и если обновление этого документа выполнено, он вставляет новый документ в коллекцию "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();

    }
} );

};

1 Ответ

0 голосов
/ 28 ноября 2018

Возможно, проблема в том, что одно из ваших значений из цикла for обновляется слишком быстро, поэтому значение изменяется между асинхронными задачами.В этом случае вы можете попытаться обернуть код, который использует эти значения, в выражения функций, вызываемых немедленно (IIFE), чтобы значения оставались внутри.Посмотрите эти 2 следующих примера: асинхронная задача моделируется с таймаутом.Без 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);
  
}
...