자동 완성기 구축
17016 단어 autocompleteinterviewjavascript
처음부터 바닐라 js로 자동 완성기를 구축하는 작업은 다음과 같이 나눌 수 있습니다.
먼저 모의 API를 설정합니다.
// generate random response string
const randomStr = () => Math.random().toString(36).substring(2, 8);
// generate a random value within a range
// for varying response delays
const randomInRange = (min = 0, max = 5) =>
min + Math.floor(Math.random() * max);
const mockApi = (searchText, delay = 1000 * randomInRange(0, 3)) => {
const results = [];
if (searchText === "") {
return Promise.resolve(results);
}
for (let i = 0; i < randomInRange(3, 5); i++) {
results.push(`${searchText} - ${randomStr()}`);
}
return new Promise((resolve, reject) => {
window.setTimeout(() => {
randomInRange(0, 25) === 24
? reject("Internal server error")
: resolve(results);
}, delay);
});
};
HTML 부분
<div>
<input id="searchbox" />
<div id="resultbox" />
</div>
AutoCompleter는 수신할 입력 필드와 결과를 전달하기 위한 콜백의 두 가지 매개변수를 허용합니다.
mockApi를 호출하는 keyup 이벤트를 추가하고 결과를 기다리며 완료되면 결과와 함께 콜백 함수를 호출합니다.
한 가지 일반적인 시나리오는 순서가 잘못된 응답을 처리하는 것입니다. search#1은 3초 후에 돌아왔고 search#2는 1초 이내에 응답했을 수 있습니다. 이를 위해 클로저를 사용하여 최신 쿼리를 추적하거나 콜백을 실행하기 전에 검색 필드의 텍스트를 확인해야 합니다.
function AutoCompleter(searchBox, doneCallback) {
let latestQuery = "";
// search action
async function triggerSearch(event) {
try {
const text = event.target.value;
latestQuery = text; // keep track of latest search text
const result = await mockApi(text);
// handle delays
if (latestQuery === text) {
doneCallback(result);
}
} catch (err) {
console.log("api error");
}
}
// add event listener
searchBox.addEventListener("keyup", triggerSearch);
// way to remove the listener
return {
clear: () => {
searchBox.removeEventListener("keyup", triggerSearch);
}
};
}
키를 누를 때마다 검색을 트리거하면 원치 않는 호출이 여러 번 발생할 수 있으므로 사용자가 입력을 일시 중지할 때만 검색을 트리거하는 것이 좋습니다. 디바운싱 및 조절에 대해 자세히 알아보기here
function debouce(fn, delay=250) {
let timeoutId = null;
return (...args) => {
if (timeoutId) {
clearTimeout(timeoutId);
}
timeoutId = setTimeout(() => {
fn(...args);
}, delay);
};
}
검색을 위해 디바운스된 기능 사용
const debouncedSearch = debouce(triggerSearch, 250);
// add event listener
searchBox.addEventListener("keyup", debouncedSearch);
자동 완성기 호출
const searchInstance = new AutoCompleter(document.getElementById("searchbox"), (output) => {
document.getElementById("resultbox").innerText = output;
});
// searchInstance.clear();
최신 쿼리를 확인하면 응답이 지연되는 문제가 해결되지만 주요 문제에 대한 가능한 추가 질문은 최신 약속을 얻는 문제에 대한 일반적인 솔루션을 구현하는 것입니다.
function latestPromise(fn) {
let latest = null;
return (...args) => {
latest = fn(...args); // update the latest promise
return new Promise(async (resolve, reject) => {
const current = latest;
try {
const res = await current;
// check before resolving
current === latest ? resolve(res) : console.log("skip");
} catch (err) {
reject(err);
}
});
};
}
몇 가지 빠른 테스트
const wrappedMockApi = latestPromise(mockApi);
async function searchAction(text, delay) {
const res = await wrappedMockApi(text, delay);
console.log("res", res);
}
searchAction("search-1", 1000);
searchAction("search-2", 400);
searchAction("search-3", 200);
searchAction("search-4", 100);
// response log will show value only for search-4
// reminaining will be skipped
대부분의 경우 모의 API와 HTML은 상용구의 일부가 되며 나머지 코드를 작성하는 데 약 40분이 소요됩니다.
작업 코드를 볼 수 있습니다 here
Reference
이 문제에 관하여(자동 완성기 구축), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/ksankar/build-an-autocompleter-359h텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)