2013-12-21 2 views
1

Я создаю небольшой инструмент для создания отчетов с помощью Node.js, и перед некоторыми проблемами с Javascript я сталкиваюсь. Я вызываю функцию, и она должна возвращать массив с городами из запроса базы данных. Здесь функция.Js function return undefined

function queryBuilderZone() { 
    var includedCities = new Array(); 
    q = heredoc(function(){/* 
     SELECT majlis.MajlisId 
     FROM majlis 
     WHERE majlis.ZoneId = -ZONE- 
    */}); 
    q = q.replace(/-ZONE-/g, inZone); 

    connection.query(q, function(err, rows, fields) { 
     if (err) throw err; 
     var rowsLentgh = rows.length; 
     for (var i = 0; i < rowsLentgh; i++) { 
       includedCities.unshift(rows[i].MajlisId); 
     }; 
     console.log(includedCities); // <-- output correct: ['...', '....'] 
    }); 
    connection.end(); 
    console.log(includedCities); // <-- output wrong: [] 
    return includedCities; 

}

Это мой вызов из основной программы

includedCities = queryBuilderZone(); 
console.log(includedCities); // <-- output wrong: [] 

Где проблема и почему эта функция не возвращает элементы массива includedCities?
И в области connection.query отображается правильное и ожидаемое значение.

Кстати, я использую модуль mysql для построения запроса и замены заполнителя в запросе.

+0

Стандартный асинхронный чехол. Ваш «ошибочный» консольный журнал появляется до завершения обратного вызова? И «includeCities» - это переменная, локальная для вашей функции. – npup

+0

Мне кажется, что это проблема обзора. Я не человек node.js, но includeCities определен в функции queryBuilderZone, которая не находится в глобальной области. Переместите его над функцией в глобальную область. –

+0

@rontornambe это очень типичная проблема новичка node.js, который не нашел времени, чтобы прочитать небольшой учебник. – hgoebl

ответ

3

Что здесь происходит, это разница между обратным вызовом и обратным вызовом. В связи с тем, что функция connection.query() должна протянуть руку, чтобы получить ее информацию, функция queryBuilderZone() продолжит работу после ее начала, а затем дойдет до вывода, что includedCities является и пустым массивом, потому что он в это время.

То, что вы хотите сделать, это пропуск в обратный вызов queryBuilderZone, что-то вроде этого

function queryBuilderZone(callback) { 
    var includedCities = new Array(); 
    q = heredoc(function() { 
     /* 
     SELECT majlis.MajlisId 
     FROM majlis 
     WHERE majlis.ZoneId = -ZONE- 
    */ 
    }); 
    q = q.replace(/-ZONE-/g, inZone); 

    connection.query(q, function (err, rows, fields) { 
     if (err) throw err; 
     var rowsLentgh = rows.length; 
     for (var i = 0; i < rowsLentgh; i++) { 
      includedCities.unshift(rows[i].MajlisId); 
     }; 
     console.log(includedCities); // <-- output correct: ['...', '....'] 
     callback(includedCities); 
    }); 
    connection.end(); 
    console.log(includedCities); // <-- output wrong: [] 
    // return includedCities; Not needed 
} 

Затем, когда вы хотите использовать его, вы могли бы сделать так, как это.

queryBuilderZone(function(includedCities) { 
    // Do what you'd like here 
    console.log(includedCities); // <-- output correct: ['...', '....'] 
}); 

Что бы ни в функции обратного вызова будет выполняться после того, как connection.query запускает свой курс, и выплевывает массив.

+1

спасибо! Я не знал о обратных вызовах. Поэтому я просто пытаюсь изучить и решить проблему одновременно. Хотя я мог бы решить это на других языках. У меня есть хороший учебник для обратного вызова, и не стесняйтесь поделиться им :) – imalik8088