СООБЩЕНИЕ, не завершенное ранее.then() выполняется в асинхронном вызове

#javascript #reactjs #flask #async-await #fetch

#javascript #reactjs #flask #async-ожидание #выборка

Вопрос:

Я делаю запрос POST, который занимает ~ 10 секунд для завершения… но мое предупреждение отображается сразу после щелчка, прежде чем сервер вернет 200. Почему? И как мне исправить это, чтобы дождаться завершения работы сервера?

 const handleClick = async () => {
    const response = await fetch("/create", {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
        },
        body: JSON.stringify(highlights),
    }).then(alert("hi!"));
};
  

Если я изменю свой .then на
.then(() => {alert("hi!");}) как было предложено ниже, страница мигает /, кажется, обновляется при выполнении запроса сервера , но предупреждение вообще не отображается

Обновить:

Если я использую этот код:

 const handleClick = async () => {
    try {
        const response = await fetch("/create", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
            },
            body: JSON.stringify(highlights),
        });
        alert("first");
    } catch (error) {}
    alert("second");
};

  

Второе предупреждение срабатывает сразу после нажатия кнопки, первое предупреждение никогда не срабатывает.

Ответ №1:

Async / await вводится для устранения проблемы с цепочкой then / catch. Вам не нужно использовать then , вы должны использовать try / catch. async / await всегда используется только с try / catch.

 
const handleClick = async () => {
try{
    const response = await fetch("/create", {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
        },
        body: JSON.stringify(highlights),
    })
alert("hi!")
}
catch(error){}
}
  

Когда вы используете try / catch , управление не будет продолжаться до завершения вызова ввода-вывода. Таким образом, вы также можете поместить предупреждение или любой код из блока try catch. Он будет выполнен после завершения вызова await.
Вот так

 
try{
    const response = await fetch("/create", {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
        },
        body: JSON.stringify(highlights),
    })

}
catch(error){}
}
alert("hi!")
  

Попробуйте это.

Если вы используете reactjs и nodejs, то я смоделировал ваше требование, и оно работает так, как ожидалось. Я использовал перехватчики reactjs. Оповещение срабатывает после успешного завершения post-вызова.

Вы можете это проверить. https://github.com/ajaysikdar/reactjs-nodejs-alert

Комментарии:

1. Спасибо за ответ, но на самом деле это не соответствует моему пониманию. Поскольку асинхронная функция всегда возвращает обещание (это просто синтаксический сахар вместо обещаний), и .then() и .catch() работают хорошо. (Ваше решение также не меняет поведение)

2. @Lumen async и await — это замена цепочек обещаний. Вам нужно дождаться обещания. Не используйте then . Вы говорите, что await — это синтаксический сахар, но для чего это синтаксический сахар, если вам все еще нужно использовать then ?

3. @JMadelaine понял. Однако это все еще не решает мою основную проблему. Есть идеи? чтобы прояснить мою проблему: если я просто «ожидаю», выполняется запрос сервера, и после него ничего (в данном случае, предупреждение) не выполняется.

4. Вы уверены, что правильно его реализовали? Этот ответ выглядит правильным для меня. Оповещение должно быть внутри асинхронной функции и после ожидания.

5. как вы запускаете эту функцию? Если это кнопка отправки формы, убедитесь, что вы используете e.preventDefault() .

Ответ №2:

Попробуйте:

 .then(() => { alert("hi"); });
  

then Функция ожидает, что вы передадите ей функцию, но на самом деле вы вызываете функцию ( alert ) и передаете возвращаемое значение этой функции then .

Комментарии:

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

2. @Lumen Звучит так, как будто это внутри формы, и вы не препятствуете отправке по умолчанию

3. @charlietfl Это не внутри формы, но я все равно не обрабатываю отправку по умолчанию. Применимо ли это в данном случае?