摘要:考慮如下代碼如果用戶在和之間再次點擊的話,就有可能同時發出兩個。這是個很合理的需求,所以我特意在上提問,可惜看起來并沒有現成的輪子可以用。用下面的函數包裹原函數,如果前一次請求尚未結束,新請求會排隊。示例使用以上所有代碼按授權。
考慮如下代碼
whatever.onclick = async () => { const a = await(await fetch("step-1")).text(); const b = await(await fetch("step-2")).text(); whatever.textContent = a + b; }
如果用戶在step-1和step-2之間再次點擊的話,就有可能同時發出兩個step-1。
當然,服務器可以驗證之后通通拒掉,但是用戶體驗很差。這是個很合理的需求,所以我特意在SF上提問,可惜看起來并沒有現成的輪子可以用。
所以還是只能自己造。
用下面的函數包裹原函數,如果前一次請求尚未結束,新請求會和舊請求一起返回。
/** * Creates a function that invokes `originalFunction`, with the `this` binding * and `arguments` of the created function, while there is no other pending * excutions of `originalFunction`. Simultaneous calls to the created function * return the result of the first pending `originalFunction` invocation. * * @param {function} originalFunction async function to wrap */ const debounceAsync = originalFunction => { let currentExcution = null; const wrappedFunction = async function () { // 1. locked => return lock if (currentExcution) return currentExcution; // 2. released => apply currentExcution = originalFunction.apply(this, arguments); try { return await currentExcution; } finally { currentExcution = null; } }; return wrappedFunction; };
用下面的函數包裹原函數,如果前一次請求尚未結束,新請求會排隊。
const endOfQueue = Promise.resolve(); const overrideResult = async lastExcution => { try { await lastExcution; } finally { return endOfQueue; } } /** * Creates a function that invokes `originalFunction`, with the `this` binding * and `arguments` of the created function, while there is no other pending * excutions of `originalFunction`. Simultaneous calls to the created function * will be queued up. * * @param {function} originalFunction async function to wrap */ const queueAsync = originalFunction => { let lastExcution = endOfQueue; const wrappedFunction = async function () { // 1. queue up const myExcution = lastExcution.then(() => originalFunction.apply(this, arguments)); // 2. update queue tail + swipe excution result from queue lastExcution = overrideResult(myExcution); // 3. return excution result return myExcution; }; return wrappedFunction; }
示例使用
/** * A promisified settimeout * * @param {number} [ms=0] time to sleep in ms */ const sleep = (ms = 0) => new Promise(resolve => setTimeout(resolve, ms)); const debounceAsync_UNIT_TEST = async () => { const goodnight = debounceAsync(sleep); for (let i = 0; i < 8; i++) { goodnight(5000).then(() => console.log(Date())); await sleep(500); } console.warn("Expected output: 8 identical datetime"); }; const queueAsync_UNIT_TEST = () => { const badnight = queueAsync(i => sleep(i).then(() => { if (Math.random() > 0.5) throw new Error("uncaught error test: you should expect a console error message.") })); badnight(1000); badnight(1000); badnight(1000); badnight(1000); badnight(1000).finally(() => console.log("5s!")); badnight(1000); badnight(1000); badnight(1000); badnight(1000); badnight(1000).finally(() => console.log("10s!")); console.warn("Check message timestamps."); console.warn("Bad:"); console.warn("1 1 1 1 1:5s"); console.warn(" 1 1 1 1 1:10s"); console.warn("Good:"); console.warn("1 1 1 1 1:5s"); console.warn(" 1 1 1 1 1:10s"); }
以上所有代碼按Mozilla Public License, v. 2.0授權。
以上所有文字內容按CC BY-NC-ND 4.0授權。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/95456.html
摘要:的單線程,與它的用途有關。特點的顯著特點異步機制事件驅動。隊列的讀取輪詢線程,事件的消費者,的主角。它將不同的任務分配給不同的線程,形成一個事件循環,以異步的方式將任務的執行結果返回給引擎。 這兩天跟同事同事討論遇到的一個問題,js中的event loop,引出了chrome與node中運行具有setTimeout和Promise的程序時候執行結果不一樣的問題,從而引出了Nodejs的...
摘要:若以多線程的方式操作這些,則可能出現操作的沖突。另外,因為是單線程的,在某一時刻內只能執行特定的一個任務,并且會阻塞其它任務執行。瀏覽器事件觸發線程事件觸發線程,當一個事件被觸發時該線程會把事件添加到任務隊列的隊尾,等待引擎的處理。 首先,說下為什么 JavaScript 是單線程? 總所周知,JavaScript是以單線程的方式運行的。說到線程就自然聯想到進程。那它們有什么聯系呢? ...
摘要:標簽單線程首發地址碼農網細說單線程的一些事最近被同學問道單線程的一些事,我竟回答不上。若以多線程的方式操作這些,則可能出現操作的沖突。另外,因為是單線程的,在某一時刻內只能執行特定的一個任務,并且會阻塞其它任務執行。 標簽: JavaScript 單線程 首發地址:碼農網《細說JavaScript單線程的一些事》 最近被同學問道 JavaScript 單線程的一些事,我竟回答不上。好...
閱讀 2198·2021-09-22 10:56
閱讀 1493·2021-09-07 10:11
閱讀 1814·2019-08-30 15:54
閱讀 2301·2019-08-30 15:44
閱讀 2319·2019-08-29 12:40
閱讀 3040·2019-08-28 18:25
閱讀 1751·2019-08-26 10:24
閱讀 3200·2019-08-23 18:39