Я новичок в nodejs и ES6 и пытаюсь понять обещания. У меня есть требование повторить попытку функции запроса Dynamodb для определенных интервалов (в данном случае 5 секунд), если результат неприемлем! Итак, у меня есть такая функция:
const retryFunc = (ddbParams, numberOfRetry) => {
return new Promise((resolve, reject) => {
return DDBUtils.query(ddbParams).then(result => {
//need to return a specific number of rows from the ddb table
if (numberOfRetry > 0){
if (result.length !== 100){
numberOfRetry = numberOfRetry - 1
setTimeout(() => {
retryFunc(ddbParams, numberOfRetry)
}, 5000)
}
}
resolve(result)
}).catch(error => {
reject(error)
})
})
}
Когда запрос Dynamodb возвращает приемлемый результат (100 записей) при первом вызове, функция работает нормально и возвращает результат вызывающей стороне. Но если функцию нужно повторить, чтобы выполнить условие 100, тогда она не возвращает результат вызывающей стороне, когда она удовлетворяется! Кто-нибудь может помочь мне понять, что происходит?
Другие ответы по теме: Как 5 раз обработать ошибку подключения, а затем создать исключение и Повторить HTTP-запрос nodejs и Как вы можете повторить попытку после исключения в Javascript, используя обещания.
Другие ответы по теме: Общее решение для повторного выполнения обещания в Javascript, Получение повторной попытки, если запрос не удался, Объем памяти шаблона обещания повторных попыток.





Во-первых, избегайте Явный антипаттерн конструкции обещания - .query уже возвращает Promise, поэтому нет необходимости создавать еще один. Затем, находясь внутри вашего if (result.length !== 100){, вы должны иметь возможность связывать вместе рекурсивные вызовы retryFunc; вы не можете напрямую return из (асинхронного, основанного на обратном вызове) setTimeout, как с вашим текущим кодом.
Один из вариантов - создать функцию delay, которая возвращает Promise, который разрешается через желаемый промежуток времени - тогда вы можете использовать return delay(5000).then(() => retryFunc(ddbParams, numberOfRetry - 1)) для возврата рекурсивного вызова.
const delay = ms => new Promise(res => setTimeout(res, ms));
const retryFunc = (ddbParams, numberOfRetry) => {
return DDBUtils.query(ddbParams).then(result => {
if (numberOfRetry > 0 && result.length !== 100) {
return delay(5000).then(() => retryFunc(ddbParams, numberOfRetry - 1));
}
});
}
Спасибо. Это очень просто.
Есть несколько подобных вопросов, на которые уже есть ответы здесь о переполнении стека. Воспользуйтесь поиском и попробуйте найти некоторые из предыдущих.