2016-09-18 3 views
0

В настоящее время я пишу backend API для частной системы сообщений, и я столкнулся с проблемой написания одной из моих функций. Мне нужно сохранить ответ асинхронного вызова на переменную для использования вне указанного асинхронного вызова.Сохраните ответ mysql-запроса на переменную для последующего использования

Я представлю код, прежде чем объяснить далее:

app.get("/api/users/:UserID/messages/deletemessage/:MessageID", function(req, res){ 

    var messageID = parseInt(req.params.MessageID); 
    var message = null; 

    connection.query("SELECT * FROM Message WHERE MessageID = ?", messageID, function(err, resp){ 
     if(!err){ 
      message = resp[0]; 
     } 
    }); 
    console.log(message); 
    //continue using the message variable here to perform more functionality... 
}); 

Вы можете видеть, что я пытаюсь присвоить переменную message в ответ на запрос выбора базы данных MySQL.

Когда функция запускается, на экран выводится null. Я знаю, почему это происходит, потому что оператор console.log вызывается до завершения запроса к базе данных.

Мой вопрос: как исправить эту проблему, чтобы использовать переменную сообщения за пределами области запроса к базе данных?

Я пробовал только это, который не работал:

app.get("/api/users/:UserID/messages/deletemessage/:MessageID", function(req, res){ 

    var messageID = parseInt(req.params.MessageID); 
    var message = null; 

    connection.query("SELECT * FROM Message WHERE MessageID = ?", messageID, function(err, resp){ 
     if(!err){ 
      connection.end(); //try to end the connection so hopefully it assigns 
      message = resp[0]; 
     } 
    }); 
    console.log(message); 
    //continue using the message variable here to perform more functionality... 
}); 
+0

Вы не «исправляете» его, вы кодируете его, ожидаете результата, прежде чем делать что-либо еще и т. Д. – adeneo

+0

@adeneo есть приемлемый или стандартный способ «кодирования вокруг него»? Что, если мне нужно сразу же использовать результат? Есть ли способ ждать? – JavascriptLoser

+0

Конечно, вы используете обратные вызовы или выполняете обещания ждать результата. Как вы решаете проблему, зависит от того, как вы используете возвращаемые данные, и о причине необходимости * иметь ее сразу *. – adeneo

ответ

0

В Node.js вы должны переместить заявление журнала в функции запроса, где присваивается переменная message.

Узел не ожидает, что этот запрос будет выполнен до регистрации. Узел просто передает данные из одного места в другое, он действительно не ждет или «блокирует» с его асинхронного языка.

Таким образом, путь вокруг него заключается в вызове одной функции внутри другой, внутри другой и другой, и вы можете подумать, что это становится беспорядочным, и это действительно так. Это называется callback hell.

Есть способы обойти, и многие из них сегодня стали стандартами. Функции обратного вызова становятся действительно беспорядочными и приводят к обратному аду, поэтому просто используйте Promise Chains или Yield expressions.

Условные выражения работают в функциях генератора. Они в основном регулярные функции с * после function, как это:

function*() { 
    // generator function 
    // you can use the "yield" keyword here 
} 

Просто голые в виду, что хотя Node.js не интерпретирует функции генератора по умолчанию. Вы должны использовать модуль, такой как co, который позволяет запускать их.

co довольно прост в использовании. Просто поместите функции генератора внутри co-функции, и это сработает. Как это:

var co = require('co'); 

co(function*() { 
    // you can yield here 
}); 

Так что ваш код может выглядеть примерно так:

var co = require('co'); 

app.get("/api/users/:UserID/messages/deletemessage/:MessageID", function(req, res){ 
    co(function*() { 
     var messageID = parseInt(req.params.MessageID); 

     var resp = yield connection.query("SELECT * FROM Message WHERE MessageID = ?", messageID); 
     // NOTE THE YIELD^

     var message = resp[0]; 
     console.log(message); 
    }); 
}); 

Несколько вещей, чтобы обнажить в виду о доходности выражений и функций генератора:

  • co просто интерпретатор функций генератора для Node v4.x и ниже, Node v6.x интерпретирует функции генератора из коробки, поэтому вам это не понадобится.
  • использовать выражение урожайности с базой данных запросов вы собираются, должен заменить модуль базы данных с одним, который поддерживает co или обещания, как https://www.npmjs.com/package/mysql-promise же самое для любого другого модуля, вы можете только дать свои результаты, если они поддерживают обещание или co
  • express.js требует, чтобы вы использовали co для добавления поддержки генератора, но есть еще один веб-фреймворк с именем Koa, который заменяет функцию в app.get функцией генератора. Таким образом, вы можете напрямую работать внутри функции запроса.
Смежные вопросы