我正在构建一个简单的服务器来接收电子邮件,
useFetch()
方法会抛出一个错误,因为这行const data = await response.json();
它告诉我“无法读取未定义的属性(读取'json')”,尽管我在另一个程序上使用完全相同的代码。
奇怪的是我上次测试这个程序时它没有产生任何错误。此外,它仍然可以发送电子邮件。
这是调用
useFetch()
的方法:
import { useFetch } from "./fetchData.js";
export const sendEmail = async (data) => {
try {
const result = await useFetch("/sendEmail", data);
if(result.status === "success")
{
console.log("ok");
/* code to inform the user that the email was sent*/
setTimeout(() => location.assign("/"), 1.5 * 1000);
}
if (result.status !== "success") return;
} catch (error) {
console.log(error.message);
}
};
useFetch()
方法:
const timeout = () => {
new Promise((_, reject) => {
setTimeout(
() => reject(Error("Something went wrong, please try again")),
5000
);
});
};
export const useFetch = async (url, emailData) => {
try {
const request = fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(emailData),
});
const response = await Promise.race([request, timeout(),]);
const data = await response.json();
if (!response.ok) throw Error(data.message);
return data;
} catch (error) {
if (error.message === "Failed to fetch")
error.message = `Unable to reach the server. Please check your internet connection...`;
throw error;
}
};
我们需要了解代码在做什么以及它的行为方式:
const response = await Promise.race([request, timeout(),]);
Promise.race
是一个静态函数,只要提供的任何可迭代承诺在其中解析,它就会解决,这意味着无论是请求还是超时,无论先解析什么,您的代码都会移动到下一行来执行它。现在,如果任何承诺失败,它将解决并且不会返回任何内容,这就是 const data = await response.json()
失败的原因。
现在,当您说电子邮件已发送,因为您发送了请求,并且它处理了电子邮件,但稍后解决了它,并且您的代码没有等待,因为您没有要求它这样做。
您对代码的期望是在需要很长时间的情况下取消请求。您可以在这里找到解决方案。