Дождитесь завершения процесса асинхронного / обещания nodeJs перед отправкой ответа клиенту - PullRequest
0 голосов
/ 13 ноября 2018

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

Я пробовал несколько вещей, перемещал их и добавлял некоторые .then () и .catch () блоки, которые могут даже не понадобиться.Я все еще довольно новичок в NodeJ, поэтому, хотя я понимаю, как все работает, я все еще не привык к асинхронному кодированию.

let markStepsComplete = async function() {

let stepsToProcess = new Multimap();//multimap JS npm
let results = await dbUtils.getCompletedSteps();
results.forEach(result => {
    stepsToProcess.set(result.ticket_id, result.step_id);
});
return new Promise((resolve,reject)=>{
    stepsToProcess.forEachEntry(async function(entry, key) {
        let payload = {
            ticketId: key,
            stepIds: entry
        }
        let response = await updateStep(payload)//returns promise
            if (response.statusCode === 200) {
                await Promise.all(payload.stepIds.map(async (stepId) => {
                    try {
                        await dbUtils.markStepsCompleted(stepId, payload.ticketId);
                    } catch(err) {
                        reject(err);
                    }
                }));
            }
            else {
                await Promise.all(payload.stepIds.map(async (stepId) => {
                try {
                    await dbUtils.markStepsProcessed(stepId, payload.ticketId, response.statusCode);
                } catch(err) {
                    console.log(err);
                    reject(err);    
                }
                }));

            }


    });
    resolve('Steps Marked Complete');  


});//promise end



}

Это путь, который я сейчас тестирую и который вызывает вышеупомянутый метод.Метод updateStep () - это метод, который фактически вызывает HTTP-запрос к внешнему API REST.Кажется, это работает, возвращая обещание.

app.use('/api/posts',async (req,res,next)=>{

let data = await markStepsComplete.markStepsComplete()
.then((data)=>{
    res.status(200).json({message: data})
})
.catch((e)=>{
    console.log('error from catch:',e);
})

})

Приведенный выше код запускается и выполняет некоторые операции в нашей базе данных в рамках этого процесса, но я получаю сообщение о разрешении «Шаги отмечены как завершенные» до завершения процесса.Поскольку разрешение решается до завершения процесса, я никогда не смогу вернуть ни одной из ошибок reject () клиенту, так как решение уже вызвано.

Заранее спасибо.

1 Ответ

0 голосов
/ 13 ноября 2018

Я заметил этот фрагмент и хотел вызвать его, потому что он не работает:

payload.stepIds.forEach(async (stepId) => {
  try {
    await dbUtils.markStepsProcessed(stepId, payload.ticketId, response.statusCode);
  } catch(err) {
    console.log(err);
    reject(err);    
  }
});

при циклическом просмотре массива элементов, требующих асинхронной выборки, вы можете сделать что-то вроде:

await Promise.all(payload.stepIds.map(async (stepId) => {
  try {
    await dbUtils.markStepsProcessed(stepId, payload.ticketId, response.statusCode);
  } catch(err) {
    console.log(err);
    reject(err);    
  }
}));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...