如何在 Yup.test 上设置超时?
how to do setTimeout on Yup.test?
我正在尝试验证地址:
line1: Yup.string()
.test(
"Address Line 1 Validation Test",
"Please enter valid Line 1 address",
async (line1: string) => {
let delayTimer = null;
let isValid = false;
const doSearch = () => {
clearTimeout(delayTimer);
delayTimer = setTimeout(async () => {
const { data } = await axios.get<{ status: string }>(
"https://maps.googleapis.com/maps/api/geocode/json?components=country:USA",
{
params: {
address: line1,
key: GEOCODE_API_KEY,
},
}
);
console.log("line1: ", line1);
console.log("data: ", data);
isValid = data.status === "OK" ? true : false;
}, 1000); // Will do the ajax stuff after 1000 ms, or 1 s
};
doSearch();
return isValid;
}
)
.required("Line 1 is required"),
我想像这样集成延迟搜索,这样我就不会在每次用户输入时都淹没我的api:AJAX: Delay for search on typing in form field
但它会在每次用户输入时执行 api 请求。我该如何实施?
问题是您实际上从未清除超时。
每次您的处理程序运行时,都会创建并初始化新的 delayTimer
、isValid
和 doSearch
变量。这些变量必须放在外部范围内。像这样:
let delayTimer = null;
let isValid = false;
Yup.string()
.test(
'Address Line 1 Validation Test',
'Please enter valid Line 1 address',
async (line1: string) => {
clearTimeout(delayTimer);
delayTimer = setTimeout(async () => {
const {data} =
(await axios.get) <
{status: string} >
('https://maps.googleapis.com/maps/api/geocode/json?components=country:USA',
{
params: {
address: line1,
key: GEOCODE_API_KEY
}
});
console.log('line1: ', line1);
console.log('data: ', data);
isValid = data.status === 'OK';
}, 1000); // Will do the ajax stuff after 1000 ms, or 1 s
return isValid;
}
)
.required('Line 1 is required');
现在,即使这解决了您最初的问题,还有另一个问题需要解决。您的函数将始终 return 具有错误值 isValid
的承诺。
你必须做什么取决于你想要什么,但我会给你以下见解:
let delayTimer = null;
let isValid = false;
let resolveRef = null;
Yup.string()
.test(
'Address Line 1 Validation Test',
'Please enter valid Line 1 address',
async (line1: string) => {
clearTimeout(delayTimer);
if (resolveRef) {
resolveRef(isValid);
resolveRef = null;
}
return await new Promise((resolve) => {
resolveRef = resolve;
delayTimer = setTimeout(async () => {
const {data} =
(await axios.get) <
{status: string} >
('https://maps.googleapis.com/maps/api/geocode/json?components=country:USA',
{
params: {
address: line1,
key: GEOCODE_API_KEY
}
});
isValid = data.status === 'OK';
resolve(isValid);
resolveRef = null;
}, 1000);
});
}
)
.required('Line 1 is required');
希望它有效。请告诉我。
我正在尝试验证地址:
line1: Yup.string()
.test(
"Address Line 1 Validation Test",
"Please enter valid Line 1 address",
async (line1: string) => {
let delayTimer = null;
let isValid = false;
const doSearch = () => {
clearTimeout(delayTimer);
delayTimer = setTimeout(async () => {
const { data } = await axios.get<{ status: string }>(
"https://maps.googleapis.com/maps/api/geocode/json?components=country:USA",
{
params: {
address: line1,
key: GEOCODE_API_KEY,
},
}
);
console.log("line1: ", line1);
console.log("data: ", data);
isValid = data.status === "OK" ? true : false;
}, 1000); // Will do the ajax stuff after 1000 ms, or 1 s
};
doSearch();
return isValid;
}
)
.required("Line 1 is required"),
我想像这样集成延迟搜索,这样我就不会在每次用户输入时都淹没我的api:AJAX: Delay for search on typing in form field
但它会在每次用户输入时执行 api 请求。我该如何实施?
问题是您实际上从未清除超时。
每次您的处理程序运行时,都会创建并初始化新的 delayTimer
、isValid
和 doSearch
变量。这些变量必须放在外部范围内。像这样:
let delayTimer = null;
let isValid = false;
Yup.string()
.test(
'Address Line 1 Validation Test',
'Please enter valid Line 1 address',
async (line1: string) => {
clearTimeout(delayTimer);
delayTimer = setTimeout(async () => {
const {data} =
(await axios.get) <
{status: string} >
('https://maps.googleapis.com/maps/api/geocode/json?components=country:USA',
{
params: {
address: line1,
key: GEOCODE_API_KEY
}
});
console.log('line1: ', line1);
console.log('data: ', data);
isValid = data.status === 'OK';
}, 1000); // Will do the ajax stuff after 1000 ms, or 1 s
return isValid;
}
)
.required('Line 1 is required');
现在,即使这解决了您最初的问题,还有另一个问题需要解决。您的函数将始终 return 具有错误值 isValid
的承诺。
你必须做什么取决于你想要什么,但我会给你以下见解:
let delayTimer = null;
let isValid = false;
let resolveRef = null;
Yup.string()
.test(
'Address Line 1 Validation Test',
'Please enter valid Line 1 address',
async (line1: string) => {
clearTimeout(delayTimer);
if (resolveRef) {
resolveRef(isValid);
resolveRef = null;
}
return await new Promise((resolve) => {
resolveRef = resolve;
delayTimer = setTimeout(async () => {
const {data} =
(await axios.get) <
{status: string} >
('https://maps.googleapis.com/maps/api/geocode/json?components=country:USA',
{
params: {
address: line1,
key: GEOCODE_API_KEY
}
});
isValid = data.status === 'OK';
resolve(isValid);
resolveRef = null;
}, 1000);
});
}
)
.required('Line 1 is required');
希望它有效。请告诉我。