[英]Promise 2 resolves before the Promise 1
我在文本字段中进行搜索,当我输入时,有一个调用在100ms之后进入后端。
例如,如果我们搜索“5041”并立即搜索“50”并再次将其设为“5041”,那么对后端进行3次调用。
1."5041" -> Promise 1
2."50" -> Promise 2
3."5041" -> Promise 3
但是,承诺3(网络电话需要200毫秒)在承诺2(网络电话需要500毫秒)之前解决,这使得屏幕反映了承诺2(“50”)的结果,当我在文本字段中的所有内容都是“5041”时。
我需要一些方法让用户输入文本字段而不会阻止用户,并且只能显示最后一次调用的结果。
这一点是可以用实现switchMap
从rxjs以成角度的应用程序。 但是我需要一种在vanilla JS中实现相同的方法。
首先,您可以将fetchData
函数包装成fetchLatestSearchResults
函数,该函数记录网络调用的时间并返回所有网络调用的最新结果 (无论从服务器返回什么数据)
const generateLatestSearchFetch = function(fetchFunc){ let mostRecentResult = null; let mostRecentResultFetchTime = Date.now(); return (...args) => { const myFetchStartTime = Date.now(); return fetchFunc(...args) .then(data => { if (myFetchStartTime > mostRecentResultFetchTime) { mostRecentResult = data; mostRecentResultFetchTime = myFetchStartTime } return mostRecentResult; }); } };
使用喜欢 :
fetchData = generateLatestSearchFetch(fetchData);
fetchData('10'); // resolves first and returns result for 10
fetchData('102'); // resolves third and returns result for 1024
fetchData('1024'); // resolves second and returns result for 1024
最后但并非最不重要的是, 在此更多地使用debounce
来优化为每个类型事件进行的网络调用次数。
你需要一个“最后”功能:
// takes a function returning a promise and only reports the last resort
function last(fn) {
let p;
return function(...args) {
let current = fn(); // call the function
p = current; // mark it as the last call
return p.then(result => {
// ask am I still the last call?
if (p === current) return result;
else return new Promise(() => {}); // never resolve
});
}
}
let onlyLastSearch = last((name) => fetch('/api?name=' + name));
onlyLastSearch('a'); // will be ignored
onlyLastSearch('b'); // will be ignored
onlyLastSearch('c'); // only relevant result
您可以使用观察者模式。
const createWrapper = (fn) => {
let counter = 0;
let lastFetchId = 0;
const listeners = [];
return {
fetch: (str) => {
let id = ++counter;
fn(str).then((data) => {
if(id > lastFetchId) {
listeners.forEach(fn => {
fn(data);
});
lastFetchId = id;
}
});
},
listen: (fn) => {
listeners.push(fn);
return () => {
const index = listeners.indexOf(fn);
listeners.splice(index, 1);
};
}
}
}
const SearchWrapper = createWrapper(fetchData);
SearchWrapper.fetch('a');
SearchWrapper.fetch('b');
SearchWrapper.fetch('c');
SearchWrapper.listen((data) => {
console.log(data);
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.