繁体   English   中英

承诺2在承诺1之前解决

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM