Мангуст не ждет доставки документа в обратном вызове - PullRequest
0 голосов
/ 16 октября 2018

в моем проекте expressjs я делаю несколько вызовов базы данных, которые зависят друг от друга.Для вызовов в базу данных postgresql я использую pg-обещание, а для вызовов mongoDB я использую mongoose.Все работает нормально, кроме того, что иногда случается, что обратный вызов мангуста findoneandupdate () не ожидает передачи документа, что приводит к тому, что следующая функция пропускает данные

вывод журнала из кода, работающего как ожидалось

5bc5a2da466f37f300d983b1 5bc5a2da466f37f300d983ba 5bc5a2da466f37f300d983b7 [ 5bc5a2da466f37f300d983b1, 5bc5a2da466f37f300d983ba, 5bc5a2da466f37f300d983b7 ]

журнал вывода кода, выполняемого, когда обратный вызов не запрашивает документ до выполнения следующего вызова базы данных

5bc5a2da466f37f300d983b1 5bc5a2da466f37f300d983b7 [ 5bc5a2da466f37f300d983b1, 5bc5a2da466f37f300d983b7 ] 5bc5a2da466f37f300d983ba

Этоотрывок кода маршрута, где возникает проблема.Команды регистрации помечены как ->

var questions = JSON.parse(req.headers.questions);
var client_jwt = req.headers.authorization;
var amcs_entry_list_array = [];



database.db.one('SELECT CASE WHEN EXISTS ( SELECT username FROM users WHERE $1 = ANY(tokens) ) THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END', client_jwt)
.then(function (data) {

    if(data.case) {
        questions.forEach(function(question_id, idx, questionsArray) {
            var question_id = question_id.questionID; 

            database.db.multi('select * from questions where id = $1;select * from choices where question_id = $1', question_id)
            .then(function (data) {

                mongoose_models_amcs_entry.amcs_entry.findOneAndUpdate(
                    {amcs_request: {question_id: question_id,request_jwt: client_jwt}},          
                    {amcs_request: {question_id: question_id,request_jwt: client_jwt},amcs_response:{ question_data: data[0], choices_data: data[1]}}, 
                    {upsert:true,new:true}, 
                    function(err, doc){
                    if (err) return handleError(err);
                    amcs_entry_list_array.push(doc._id);
                 ->   console.log(doc.id);
                    if (idx === questionsArray.length - 1){ //if last response arrived
                     ->   console.log(amcs_entry_list_array);
                        mongoose_models_amcs_entry_list.amcs_entry_list.findOneAndUpdate(
                            {amcs_entry_list: {document_ids: amcs_entry_list_array}},          
                            {amcs_entry_list: {document_ids: amcs_entry_list_array}},         
                            {upsert:true,new:true}, 
                            function(err, doc){
                            if (err) return handleError(err);
                            res.send("http://localhost:8080/entry/"+doc._id);
                        });

                    }
                });


            })
            .catch(function (error) {
                console.log("ERROR:", error);
            });


        });

    }

Как я могу заставить обратный вызов ждать, пока не будет доставлено «doc», перед выполнением обратного вызова после отмеченных команд console.log ()?

1 Ответ

0 голосов
/ 16 октября 2018

Предполагается, что вы используете es2016.При этом ваш код будет ждать результата и не будет переходить к следующей инструкции.Вы можете зайти сюда, чтобы узнать больше https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

Для справки ваш код будет таким:

database.db.one('SELECT CASE WHEN EXISTS ( SELECT username FROM users WHERE $1 = ANY(tokens) ) THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END', client_jwt)
.then(function (data) {

if(data.case) {
        questions.forEach(async function(question_id, idx, questionsArray) {
         var question_id = question_id.questionID; 
     var data = await database.db.multi('select * from questions where id = $1;select * from choices where question_id = $1', question_id)

    var output = await mongoose_models_amcs_entry.amcs_entry.findOneAndUpdate(
                                {amcs_request: {question_id: question_id,request_jwt: client_jwt}},          
                                {amcs_request: {question_id: question_id,request_jwt: client_jwt},amcs_response:{ question_data: data[0], choices_data: data[1]}}, 
                                {upsert:true,new:true})
     if (!optput._id) return handleError(err);
                amcs_entry_list_array.push(doc._id);
     console.log(doc.id);
     if (idx === questionsArray.length - 1){ //if last response arrived
           console.log(amcs_entry_list_array);
 var out1 = await mongoose_models_amcs_entry_list.amcs_entry_list.findOneAndUpdate(
                                            {amcs_entry_list: {document_ids: amcs_entry_list_array}},          
                                            {amcs_entry_list: {document_ids: amcs_entry_list_array}},         
                                            {upsert:true,new:true}) 
    if (!out1._id) return handleError(err);
    res.send("http://localhost:8080/entry/"+doc._id);
                    }
                    });
        }
        })
        .catch(function (error) {
                console.log("ERROR:", error);
        });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...