国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Javascript是單線程的,還會出現數據競爭嗎?當然會!

Awbeci / 2061人閱讀

摘要:考慮如下代碼如果用戶在和之間再次點擊的話,就有可能同時發出兩個。這是個很合理的需求,所以我特意在上提問,可惜看起來并沒有現成的輪子可以用。用下面的函數包裹原函數,如果前一次請求尚未結束,新請求會排隊。示例使用以上所有代碼按授權。

考慮如下代碼

whatever.onclick = async () => {
    const a = await(await fetch("step-1")).text();
    const b = await(await fetch("step-2")).text();
    whatever.textContent = a + b;
}

如果用戶在step-1step-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

相關文章

  • 瀏覽器知識

    摘要:瀏覽器的渲染進程是多線程的。異步請求線程在在連接后是通過瀏覽器新開一個線程請求將檢測到狀態變更時,如果設置有回調函數,異步線程就產生狀態變更事件,將這個回調再放入事件隊列中。 [TOC] 瀏覽器進程線程 區分線程和進程 **- 什么是進程** 狹義定義:進程是正在運行的程序的實例(an instance of a computer program that is being exe...

    Pluser 評論0 收藏0
  • JS高級入門教程

    摘要:解析首先簡稱是由歐洲計算機制造商協會制定的標準化腳本程序設計語言。級在年月份成為的提議,由核心與兩個模塊組成。通過引入統一方式載入和保存文檔和文檔驗證方法對進行進一步擴展。其中表示的標記位正好是低三位都是。但提案被拒絕了。 JS高級入門教程 目錄 本文章定位及介紹 JavaScript與ECMAScript的關系 DOM的本質及DOM級介紹 JS代碼特性 基本類型與引用類型 JS的垃...

    zsy888 評論0 收藏0
  • JS與Node.js中事件循環

    摘要:的單線程,與它的用途有關。特點的顯著特點異步機制事件驅動。隊列的讀取輪詢線程,事件的消費者,的主角。它將不同的任務分配給不同的線程,形成一個事件循環,以異步的方式將任務的執行結果返回給引擎。 這兩天跟同事同事討論遇到的一個問題,js中的event loop,引出了chrome與node中運行具有setTimeout和Promise的程序時候執行結果不一樣的問題,從而引出了Nodejs的...

    abson 評論0 收藏0
  • 第五天 JavaScript線程詳解

    摘要:若以多線程的方式操作這些,則可能出現操作的沖突。另外,因為是單線程的,在某一時刻內只能執行特定的一個任務,并且會阻塞其它任務執行。瀏覽器事件觸發線程事件觸發線程,當一個事件被觸發時該線程會把事件添加到任務隊列的隊尾,等待引擎的處理。 首先,說下為什么 JavaScript 是單線程? 總所周知,JavaScript是以單線程的方式運行的。說到線程就自然聯想到進程。那它們有什么聯系呢? ...

    caiyongji 評論0 收藏0
  • 細說JavaScript線程一些事

    摘要:標簽單線程首發地址碼農網細說單線程的一些事最近被同學問道單線程的一些事,我竟回答不上。若以多線程的方式操作這些,則可能出現操作的沖突。另外,因為是單線程的,在某一時刻內只能執行特定的一個任務,并且會阻塞其它任務執行。 標簽: JavaScript 單線程 首發地址:碼農網《細說JavaScript單線程的一些事》 最近被同學問道 JavaScript 單線程的一些事,我竟回答不上。好...

    sarva 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<