---
# System prepended metadata

title: 寫一個有debounce的input，並檢查有沒有重複的輸入值

---

{%hackmd BJrTq20hE %}

###### tags: `Vue` `composition API` `debounce`
# 寫一個有debounce的input，並檢查有沒有重複的輸入值。

## 目的

可以驗證使用者輸入的客戶單號有沒有重複，有重複的話就跳出警告訊息。
如下圖
![](https://hackmd.io/_uploads/ry8uRpDy6.png)

## 步驟

1.當input輸入文字後的0.8秒才會發送request。

2.當response為true的時後代表重複，則觸發element plus的validation，沒回傳則不觸發。

## 地雷點
1.非同步函式的結果，不要return出來判斷，因為判斷不會等非同步函式執行後再判斷。
2.debounce如果有需要處理內部有return Promise的函式，則需要把debounce內寫成promise函式

## 怎麼做到的呢?
靠chat GPT 寫一個debounce

重點是要把所執行的函式寫成Promise，不然你的警告訊息會"困在"console內。
下面的code是重點。
```javascript=
const debounce = (fn, wait = 800) => {
  let timeout = null;
  return function () {
    const args = arguments;
    clearTimeout(timeout);
    return new Promise((resolve, reject) => {
      timeout = setTimeout(async () => {
        try {
          const result = await fn.apply(this, args);
          resolve(result);
        } catch (error) {
          reject(error);
        }
      }, wait);
    });
  };
};
```
整體的code長這樣子
要注意的是checkIsCustomerRepeatData所回傳的結果必需在裡面進行判斷，之前是return出去後再做判斷結果會晚一步。


```javascript=
const debounce = (fn, wait = 800) => {
  let timeout = null;
  return function () {
    const args = arguments;
    clearTimeout(timeout);
    return new Promise((resolve, reject) => {
      timeout = setTimeout(async () => {
        try {
          const result = await fn.apply(this, args);
          resolve(result);
        } catch (error) {
          reject(error);
        }
      }, wait);
    });
  };
};

const checkIsCustomerRepeatData = async (customerId, customerNo) => {
  const res = await checkIsCustomerRepeat({
    customerId: customerId,
    customerNo: customerNo,
  });
  if (res !== undefined) {
    if (res.data === true) {
      // res.data 為 true 代表有重複
      return Promise.reject("客戶單號重複，請修改。");
    } else if (res === undefined) {
      return Promise.resolve();
    }
  }
};

const validateCustomerOrderNo = debounce(async (rule, value) => {
  if (!props.customerId) return;

  if (initCustomerOrderNo.value === value || value === "") {
    return Promise.resolve();
  }
  return checkIsCustomerRepeatData(props.customerId, value);
});
const rules = ref({
  targetDate: [{ required: true, message: "請選擇日期", trigger: "blur" }],
  memo: [{ required: true, message: "請選擇日期", trigger: "blur" }],

  customerOrderNo: [
    {
      validator: validateCustomerOrderNo,
      trigger: "change",
    },
  ],
});
```