成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

Javascript是單線程的,還會(huì)出現(xiàn)數(shù)據(jù)競(jìng)爭(zhēng)嗎?當(dāng)然會(huì)!

Awbeci / 2058人閱讀

摘要:考慮如下代碼如果用戶在和之間再次點(diǎn)擊的話,就有可能同時(shí)發(fā)出兩個(gè)。這是個(gè)很合理的需求,所以我特意在上提問(wèn),可惜看起來(lái)并沒(méi)有現(xiàn)成的輪子可以用。用下面的函數(shù)包裹原函數(shù),如果前一次請(qǐng)求尚未結(jié)束,新請(qǐng)求會(huì)排隊(duì)。示例使用以上所有代碼按授權(quán)。

考慮如下代碼

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之間再次點(diǎn)擊的話,就有可能同時(shí)發(fā)出兩個(gè)step-1。

當(dāng)然,服務(wù)器可以驗(yàn)證之后通通拒掉,但是用戶體驗(yàn)很差。這是個(gè)很合理的需求,所以我特意在SF上提問(wèn),可惜看起來(lái)并沒(méi)有現(xiàn)成的輪子可以用。

所以還是只能自己造。

用下面的函數(shù)包裹原函數(shù),如果前一次請(qǐng)求尚未結(jié)束,新請(qǐng)求會(huì)和舊請(qǐng)求一起返回。

/**
 * 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;
};

用下面的函數(shù)包裹原函數(shù),如果前一次請(qǐng)求尚未結(jié)束,新請(qǐng)求會(huì)排隊(duì)。

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授權(quán)。
以上所有文字內(nèi)容按CC BY-NC-ND 4.0授權(quán)。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/95456.html

相關(guān)文章

  • 瀏覽器知識(shí)

    摘要:瀏覽器的渲染進(jìn)程是多線程的。異步請(qǐng)求線程在在連接后是通過(guò)瀏覽器新開(kāi)一個(gè)線程請(qǐng)求將檢測(cè)到狀態(tài)變更時(shí),如果設(shè)置有回調(diào)函數(shù),異步線程就產(chǎn)生狀態(tài)變更事件,將這個(gè)回調(diào)再放入事件隊(duì)列中。 [TOC] 瀏覽器進(jìn)程線程 區(qū)分線程和進(jìn)程 **- 什么是進(jìn)程** 狹義定義:進(jìn)程是正在運(yùn)行的程序的實(shí)例(an instance of a computer program that is being exe...

    Pluser 評(píng)論0 收藏0
  • JS高級(jí)入門(mén)教程

    摘要:解析首先簡(jiǎn)稱(chēng)是由歐洲計(jì)算機(jī)制造商協(xié)會(huì)制定的標(biāo)準(zhǔn)化腳本程序設(shè)計(jì)語(yǔ)言。級(jí)在年月份成為的提議,由核心與兩個(gè)模塊組成。通過(guò)引入統(tǒng)一方式載入和保存文檔和文檔驗(yàn)證方法對(duì)進(jìn)行進(jìn)一步擴(kuò)展。其中表示的標(biāo)記位正好是低三位都是。但提案被拒絕了。 JS高級(jí)入門(mén)教程 目錄 本文章定位及介紹 JavaScript與ECMAScript的關(guān)系 DOM的本質(zhì)及DOM級(jí)介紹 JS代碼特性 基本類(lèi)型與引用類(lèi)型 JS的垃...

    zsy888 評(píng)論0 收藏0
  • JS與Node.js中事件循環(huán)

    摘要:的單線程,與它的用途有關(guān)。特點(diǎn)的顯著特點(diǎn)異步機(jī)制事件驅(qū)動(dòng)。隊(duì)列的讀取輪詢線程,事件的消費(fèi)者,的主角。它將不同的任務(wù)分配給不同的線程,形成一個(gè)事件循環(huán),以異步的方式將任務(wù)的執(zhí)行結(jié)果返回給引擎。 這兩天跟同事同事討論遇到的一個(gè)問(wèn)題,js中的event loop,引出了chrome與node中運(yùn)行具有setTimeout和Promise的程序時(shí)候執(zhí)行結(jié)果不一樣的問(wèn)題,從而引出了Nodejs的...

    abson 評(píng)論0 收藏0
  • 第五天 JavaScript線程詳解

    摘要:若以多線程的方式操作這些,則可能出現(xiàn)操作的沖突。另外,因?yàn)槭菃尉€程的,在某一時(shí)刻內(nèi)只能執(zhí)行特定的一個(gè)任務(wù),并且會(huì)阻塞其它任務(wù)執(zhí)行。瀏覽器事件觸發(fā)線程事件觸發(fā)線程,當(dāng)一個(gè)事件被觸發(fā)時(shí)該線程會(huì)把事件添加到任務(wù)隊(duì)列的隊(duì)尾,等待引擎的處理。 首先,說(shuō)下為什么 JavaScript 是單線程? 總所周知,JavaScript是以單線程的方式運(yùn)行的。說(shuō)到線程就自然聯(lián)想到進(jìn)程。那它們有什么聯(lián)系呢? ...

    caiyongji 評(píng)論0 收藏0
  • 細(xì)說(shuō)JavaScript線程一些事

    摘要:標(biāo)簽單線程首發(fā)地址碼農(nóng)網(wǎng)細(xì)說(shuō)單線程的一些事最近被同學(xué)問(wèn)道單線程的一些事,我竟回答不上。若以多線程的方式操作這些,則可能出現(xiàn)操作的沖突。另外,因?yàn)槭菃尉€程的,在某一時(shí)刻內(nèi)只能執(zhí)行特定的一個(gè)任務(wù),并且會(huì)阻塞其它任務(wù)執(zhí)行。 標(biāo)簽: JavaScript 單線程 首發(fā)地址:碼農(nóng)網(wǎng)《細(xì)說(shuō)JavaScript單線程的一些事》 最近被同學(xué)問(wèn)道 JavaScript 單線程的一些事,我竟回答不上。好...

    sarva 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<