#javascript #promise #async-await #axios
#javascript #обещание #async-await #axios
Вопрос:
Я использую асинхронную функцию для запуска сервера, проверки возврата URL-адреса 200
, а затем запускаю свои тесты, но моя checkUrl
функция не завершается до запуска следующей строки кода.
Я использую axios
пакет для проверки URL-адреса для получения кода состояния, и я пробовал несколько вариантов async / await и Promise.resolve()
.
function checkUrl(url) {
console.log(`Checking for ${url}`);
return axios
.get(url)
.then(function(res) {
const message = `${url} is status code: ${res.status}`;
return res;
})
.catch(function(err) {
console.log("Will check again in 5 seconds");
setTimeout(() => {
return checkUrl(url);
}, 5000);
});
}
async function init() {
let val;
console.log("Running tests:::");
// start server in react-integration directory
shell.exec("BROWSER=none yarn start", {
cwd: "sampleIntegration/react-integration",
async: true
});
// check server has started
val = await checkUrl("http://localhost:3000");
console.log(`value from checkUrl promise: ${val}`);
}
Я ожидаю, что переменной val будет сообщение, возвращаемое из Promise.resolve()
моей checkUrl
функции.
val
возвращается неопределенным.
Комментарии:
1. Значение возвращается
undefined
в обоих случаях или только для случая ошибки?2.
shell.exec
является асинхронным, поэтому при вызовеcheckurl
сервер может быть еще недоступен, что приводитaxios.get
к переходу в ветку catch. Оттуда вы ничего не возвращаете, таким образом, конечный результат не определен3. консоль. журнал запускается только один раз после регистрации блока catch.
Checking for http://localhost:3000 Will check again in 5 seconds value from checkUrl promise: undefined
Как только обещание выполняется, я получаю,http://localhost:3000 is status code: 200
но строка под функцией уже запущена.4. И я также не уверен, разрешает ли axios или отклоняет, когда код состояния http равен != 2xx
5.
return
ВнутриsetTimeout
не выполняет то, что вы, вероятно, думаете, что это делает. Этот блок совершенно не связан с результатом блока catch. Фактически, ваш блок catch пока не дает никакого результатаval == undefined
.
Ответ №1:
Проблема в том, setTimeout
что в блоке catch. Это асинхронно, но блок catch немедленно возвращается. Поскольку ему нечего возвращать, он возвращает undefined. Чтобы решить эту проблему (а также сохранить желаемое поведение ожидания), вы могли бы сделать что-то вроде этого:
function checkUrl(url) {
console.log(`Checking for ${url}`);
return axios.get(url)
.then(res => {
const message = `${url} is status code: ${res.status}`;
return res;
})
.catch(err => {
console.log('Will check again in 5 seconds');
return new Promise((resolve) => {
setTimeout(resolve, 5000);
}).then(() => checkUrl(url));
});
}
Это создаст обещание, которое разрешается через 5 секунд, и при разрешении оно вызывает checkUrl .
Комментарии:
1. Отличная работа @derpirscher. Я не видел вашего ответа, но, похоже, мы находимся на одной странице. Спасибо за вашу помощь!