2016-06-28 4 views
0

Я пытаюсь переместить большой объем данных из базы данных mysql (количество больше максимального размера запроса), и для этого вам нужно запустить его через цикл в кусках. Проблема, с которой я сталкиваюсь, заключается в том, что даже при небольшом размере выборки из 50 записей я постоянно пропускаю около половины из них, поскольку кажется, что соединение закрывается до завершения цикла. Фрагмент кода, у меня возникли проблемы с ниже:Как я могу остановить соединение от закрытия раньше?

for(var j = 0; j < maxNum; j+=increment){ 
    // populates the array that can be used to find the mods that have been purchased 
    console.log("START = " + j + " END = " + (j+increment)); 
    con.query("SELECT * FROM sometable WHERE id BETWEEN " + j 
    + " AND " + (j + increment), function(err, rows, fields){ 
    if(!err){ 
     console.log("ROWS = " + rows.length); 
     for(var a = 0; a < rows.length; a++){ 
     arrayOfObjs.push(rows[a]); 
     console.log(rows[a].ID); 
     // If the inner loop is at the end and the while loop is about to end this cycle 
     if((a + 1 == rows.length) && ((userCounter + increment - 1) > maxNum)) { 
      // Loop through all the user objects and if it has records, add it to that item 
      for(var b = 0; b < arrayOfUsers.length; b++){ 
      arrayOfUsers[b].objs = returnObjById(b, arrayOfMods); 
      // If the loop is ending 
      if(b+1 == arrayOfUsers.length){ 
       done1 = true; 
       // temp force close 
       shutDown() 
      } 
      } 
     } 
     } 
    } 
    else{ 
     console.log(err); 
    } 
    }) 
} 

MAXNUM должен представлять общее количество пользователей в таблице в целом, и прирост будет размер кусков. Функция returnObjs ничего не вызывает и представляет собой простой переключатель, который не влияет на функциональность. Функция shutdown - это конец соединения mysql с process.exit для обратного вызова. Эта функция - это то, что заканчивает сценарий до его завершения, но поскольку я новичок в Node, я не знаю, как я мог бы настроить это, чтобы гарантировать, что это не будет продолжаться. Любые предложения были бы оценены, поскольку это делается частично как способ изучения Узел, так как это не составит труда сделать на языке, с которым я знаком.

+0

Возможно, из-за вашего значения тайм-аута – Drew

ответ

0

Здесь я вижу две возможные проблемы.

Во-первых, conn.query(), вероятно, является функцией async (смотря на функцию обратного вызова, которую я вижу там). Это означает, что узел не будет ждать, пока вызов будет вызван, прежде чем продолжить выполнение, в результате чего ваши первые итерации цикла будут выполняться до того, как будет вызван первый обратный вызов conn.query().

Предлагаю вам ознакомиться с этой замечательной библиотекой: async. Это помогает много работать с асинхронными операциями, например, в том случае, если вы хотите дождаться обратного вызова перед началом другой итерации. В этом случае функция async.series() может быть полезна.

Во-вторых, вы звоните в shutdown(), кажется, автоматически произойдет, когда последняя итерация третьего for цикла была закончена, но вы все еще в первой итерации ваших первых и второе for петель. Это означает, что j никогда не будет увеличиваться, равно a. Функция shutdown() должна быть вызвана в конце последней итерации вашего первого цикла for.

EDIT: Я пропустил ваш if до третьего цикла for. Я не уверен, какова цель проверки (userCounter + increment - 1) > maxNum, но если она предотвращает вызов третьего цикла, когда a или j не имеют своего максимального значения, вы можете отбросить мою вторую точку. Проблема async все еще существует, и, скорее всего, является причиной вашей проблемы.

+0

Трудно заметить с помощью вложенности, но каждый из этих циклов вызывается только после того, как предыдущий цикл находится на последнем прогоне (когда счетчик максимально допустим перед разрывом) , поэтому функция shutDown вызывается только после первого цикла, а второй цикл полностью запускает свой курс. Что касается async, я определенно рассматривал что-то подобное, но я хотел посмотреть, есть ли какая-то часть знаний, которые я потерял, о языке, который бы разрешил проблему, не прибегая к удалению асинхронной способности, поскольку это можно было бы решить, просто используя php или python – KM529

+0

Вот что я заметил позже :) Итак, проблема в том, что первый 'for' заканчивает свои итерации до вызова первого обратного вызова, тогда во время первого выполнения обратного вызова вызывается функция' shutdown() ' потому что он думает, что это последняя итерация. С помощью асинхронной библиотеки вы все равно можете сохранить асинхронный характер своего кода. Используя 'async.parallel()' (или 'async.each()', если вы просто хотите перебирать коллекцию), вы можете сказать ему, чтобы он вызывал «окончательный» обратный вызов, как только все ваши обратные вызовы завершили выполнение.В этом последнем обратном вызове async вы можете безопасно вызвать 'shutdown()'. –

+0

Хорошо, спасибо. Я обязательно посмотрю, что – KM529