2016-12-27 4 views
0

Я создал сервер с помощью NodeJS. В MySQL есть база данных и около 5000 пользователей. Я должен прочитать базу данных mysql и обновить и сделать журнал в базе данных MongoDB. Я выполнил для этого код. https://gist.github.com/chanakaDe/aa9d6a511070c3c78ba3ebc018306ad8Как управлять почти 5000 записями в цикле for в узле js-сервера?

В этом проблема. в этом коде, в строке 50, я добавил это значение.

userArray[i].ID] 

Это идентификатор пользователя из цикла for, и мне нужно обновить таблицу mysql с этим идентификатором. Все эти коды в блоке цикла for. Но я получаю эту ошибку.

TypeError: Cannot read property 'ID' of undefined

Так что я присвоил эти значения переменным в верхней части. См. Строки 38 и 39.

var selectedUserID = userArray[i].ID; 
       var selectedUserTelephone = userArray[i].telephone; 

Когда я использую это, нет ошибки. Но идентификатор пользователя не обновляется. Последние 2 значения имеют одинаковый идентификатор пользователя.

Какое решение для этого?

ответ

1

Это общая проблема JavaScript, связанная с концепциями области видимости и подъема переменных во время асинхронных операций.

var a = 0; 

function doThingWithA() { 
    console.log(a) 
} 

for (var i=0; i<1000; i++) { 
    a++; 
    setTimeout(function() { 
    doThingWithA(); 
    }, 10); 
} 

В этом примере «а» всегда будет войти со значением 1000. Причина этого заключается в том, что SetTimeout (подражает медленная работа дб) занимает много времени и в течение этого времени (до наступления журнала) " a "увеличивается до 1000, поскольку цикл for не ждет завершения setTimeout.

Лучшее решение - использовать модуль «асинхронный».

pool.getConnection(function (err, connection) { 
    connection.query(query, function (err, users) { 
    async.eachSeries(users, function (user, next) { 
     async.parallel([ 
     function updateUserStatus (cb) { /* your current code */ }, 
     function updateUserAccount (cb) { /* current code for this */ } 
     ], next); 
    }, function (err) { console.log('finished for all users!') }) 
    }); 
}); 

Вы также можете использовать обещания. Это типичная проблема async в node.js. Из чтения кода, кажется, вы считаете, что каждая операция выполняется последовательно, тогда как в узле запускается каждый вход/выход (например, вызов db), но ваш код продолжает работать, как показано в приведенном выше примере цикла for for.

+0

Ваш ответ полезным. Да, на самом деле я думал, что мой код работает сверху вниз как серия. Я сделаю этот вариант «async.parallel», и если есть какая-либо другая проблема, опубликует комментарий здесь :) Спасибо за помощь –

+0

Знаете ли вы, почему я не могу получить доступ к значению userArray [i] .ID? –

+0

@RootSL с использованием 'i' является общей проблемой при выполнении асинхронных действий в узле. Решение состоит в том, чтобы обернуть его в закрытие следующим образом: для (var i = 0; i <1000; i ++) { (функция (i) { // делать вещи }) (i); } –

0

Существует прохладная библиотека называется ES6-обещание бассейн

https://www.npmjs.com/package/es6-promise-pool

Так что имеет опцию параллелизм как:

var count = 0 
var promiseProducer = function() { 
    if (count < 5) { 
    count++ 
    return delayValue(count, 1000) 
    } else { 
    return null 
    } 
} 

var pool = new PromisePool(promiseProducer, 3) 

pool.start() 
    .then(function() { 
    console.log('Complete') 
    }) 
Смежные вопросы