是的/Formik异步验证带有反跳



如何将debounce应用于下面的异步验证(Yup的github代码(?

let asyncJimmySchema = string().test(
'is-jimmy',
'${path} is not Jimmy',
async (value) => (await fetch('/is-jimmy/' + value)).responseText === 'true',
});

您可以使用lodash.debounce:自行实现

import { debounce } from "lodash";
// .....
const ASYNC_VALIDATION_TIMEOUT_IN_MS = 1000;
const validationFunction = async (value, resolve) => {
try {
const response = await fetch('/is-jimmy/' + value);
resolve(response.responseText === 'true');
} catch (error) {
resolve(false);
}
};
const validationDebounced = debounce(validationFunction, ASYNC_VALIDATION_TIMEOUT_IN_MS);

然后在验证方案中:

let asyncJimmySchema = string().test(
'is-jimmy',
'${path} is not Jimmy',
value => new Promise(resolve => validationDebounced(value, resolve)),
});

我认为这应该有效。它复制了解决方案,只是取消反弹,但立即返回Promise,这正是Yup所期望的。

const asyncDebouncer = (fn, wait, callFirst) => {
var timeout;
return function() {
return new Promise(async (resolve) => {
if (!wait) {
const result = await fn.apply(this, arguments);
resolve(result);
}
var context = this;
var args = arguments;
var callNow = callFirst && !timeout;
clearTimeout(timeout);
timeout = setTimeout(async function() {
timeout = null;
if (!callNow) {
const result = await fn.apply(context, args);
resolve(result);
}
}, wait);
if (callNow) {
const result = await fn.apply(this, arguments);
resolve(result);
}
});
};
};
let asyncJimmySchema = string().test(
'is-jimmy',
'${path} is not Jimmy',
asyncDebouncer((value) => (await fetch('/is-jimmy/' + value)).responseText === 'true', 400),
});

最新更新