使用 lodash debounce 返回一个 promise

use*_*690 11 javascript lodash reactjs react-final-form

使用 React、react-final-form 和 lodash debounce 函数,我想验证用户名是否尚未使用(该字段使用的是 react-final-form)。

我在获取 debounce 函数以从提取请求返回已解决的承诺时遇到问题。

我提供了以下代码和框链接来演示我的问题:

请谁能告诉我为什么我的代码不起作用。

验证的入口点来自在验证属性中引用的 this.isNameUnique 调用

import React from "react";
import { Field, Form } from "react-final-form";
import { debounce } from "lodash";

class DemoForm extends React.Component {
  getIsNameUnique = name => {
    console.log("getIsNameUnique", name);

    // fake fetch request
    return async name => {
      const asyncResponse = await new Promise(resolve =>
        setTimeout(resolve({ name: true }), 1000)
      );
      console.log("async api response", asyncResponse);
      return asyncResponse;
    };
  };

  debounceCreativeName = name => {
    console.log("debounceCreativeName", name);
    return new Promise(resolve => {
      debounce(() => resolve(this.getIsNameUnique(name)), 2000);
    });
  };

  isNameUnique = async name => {
    const isNameAvailable = await this.debounceCreativeName(name);
    console.log("isNameAvailable", isNameAvailable);
    return isNameAvailable;
  };

  render() {
    return (
      <Form
        onSubmit={() => null}
        render={({ handleSubmit, reset, submitting, pristine, values }) => {
          return (
            <form onSubmit={handleSubmit}>
              <Field name="name" validate={this.isNameUnique}>
                {({ input, meta }) => {
                  return (
                    <input
                      style={{
                        display: "flex",
                        height: "40px",
                        fontSize: "24px"
                      }}
                      autoComplete="off"
                      {...input}
                      type="text"
                      placeholder="Enter the name"
                    />
                  );
                }}
              </Field>
            </form>
          );
        }}
      />
    );
  }
}

export default DemoForm;
Run Code Online (Sandbox Code Playgroud)

Dom*_*987 8

这个沙箱解决了你的问题。

你不应该在每次渲染时创建一个新的去抖动函数:

return new Promise(resolve => {
  debounce(() => resolve(this.getIsNameUnique(name)), 2000);
});
Run Code Online (Sandbox Code Playgroud)

相反,您应该只isNameUnique用去抖动包装整个函数(请参阅我的沙箱)。通过在每次点击时创建一个新的去抖动函数,它无法“记住”被调用或将被再次调用。这将防止去抖动。

此外,通过使异步,getIsNameUnique您可以降低仅使用 await 的复杂性。

  • 显示您不应该做什么,因为答案中唯一的代码并不是一个答案,沙箱也没有解决如何等待去抖函数的结果 (5认同)