最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文帶你簡單封裝JS下的異步任務(wù)對象

 更新時間:2022年11月17日 10:43:47   作者:頭疼腦脹的代碼搬運工  
我們在燒水的過程中去干了別的事情,就屬于異步模式,異步模式中不會等待異步任務(wù)的結(jié)束才開始執(zhí)行下一個同步的任務(wù),都是開啟過后就立即執(zhí)行下一個任務(wù),下面這篇文章主要給大家介紹了如何通過一文帶你簡單封裝JS下的異步任務(wù)對象的相關(guān)資料,需要的朋友可以參考下

廢話開篇:

js有微任務(wù)跟宏任務(wù),但是不管是哪種任務(wù)并不代表著會開辟新的線程,可以理解為將上述兩種任務(wù)放到“主任務(wù)”之后執(zhí)行,有點像iOS下的在主線程調(diào)用異步函數(shù)一樣,其實也只是將異步任務(wù)降低了優(yōu)先級,等主線程不忙的時候再處理該任務(wù),比如:UI任務(wù)優(yōu)先級較高,所以,任何的主線程下的異步任務(wù)都要排到UI任務(wù)結(jié)束之后進行。

一、利用 Promise 實現(xiàn)異步任務(wù)

利用 Promise 實現(xiàn)異步任務(wù),如果不加任何限制,微任務(wù)的執(zhí)行便會按添加的先后順序進行執(zhí)行。這里簡單封裝一下,實現(xiàn)微任務(wù)下的執(zhí)行依賴。可能有人會問,await 不就行了嗎?是的,聲明異步方法就能滿足,順序執(zhí)行。但是還是要整理一個過程來增加對代碼的理解。

二、實現(xiàn)效果

這里簡單的邏輯是:異步3任務(wù) -> 異步2任務(wù) -> 異步1任務(wù)

三、代碼實現(xiàn)

下面是調(diào)度代碼邏輯

function dispath(){
    console.log('異步3完成,異步2才能開始,異步2完成,異步1才能開始')
    //創(chuàng)建任務(wù)一
    let blockOperationOne = new BlockOperation((b)=>{
        console.log('異步1任務(wù)');
        //單一任務(wù)完成事件通知
        b.finished();
    });

    //添加新任務(wù)
    blockOperationOne.addExecutionBlock((b)=>{
        console.log('異步1新增任務(wù)');
        b.finished();
    });

    //創(chuàng)建任務(wù)二
    let blockOperationTwo = new BlockOperation((b)=>{
        console.log('異步2任務(wù)');
        b.finished();
    });

    blockOperationTwo.addExecutionBlock((b)=>{
        console.log('異步2新增任務(wù)2');
        b.finished();
    });

    blockOperationTwo.addExecutionBlock((b)=>{
        console.log('異步2新增任務(wù)需要等待4秒');
        setTimeout(() => {
            console.log('異步2新增任務(wù)3');
            b.finished();
        }, 4000);
    });

    //創(chuàng)建任務(wù)三
    let blockOperationThree = new BlockOperation((b)=>{
        console.log('異步3需要等待1秒');
        setTimeout(() => {
            console.log('異步3任務(wù)');
            b.finished();
        }, 1000);
    });

    //添加依賴
    blockOperationOne.addDependency(blockOperationTwo);
    blockOperationTwo.addDependency(blockOperationThree);

    //開始執(zhí)行
    blockOperationOne.start();
    blockOperationTwo.start();
    blockOperationThree.start();

    console.log('我是宏任務(wù)');
};

下面是封裝的 BlockOperation 對象

//任務(wù)通知對象
class Block{
    //完成回調(diào)
    doneCallBack = null
    constructor(doneCallBack){
        this.doneCallBack = doneCallBack
    }

    //單任務(wù)完成
    finished(){
        this.doneCallBack();
    }
}

//任務(wù)對象
class BlockOperation {
    //任務(wù)集合
    blocks = []
    //是否已開始
    isBeginStart = false
    //依賴任務(wù)對象
    dependencyOperation = null
    //被依賴影響的對象
    impactOperation = null
    //全部完成的事件判定
    allOperationIsDone = false
    //全部完成的事件回調(diào)
    allOperationDoneBlock = ()=>{
        //將依賴任務(wù)完成進行自身任務(wù)
        if(this.impactOperation){
            this.impactOperation.start()
        }
    };

    //代理
    proxy = null;
    //代理set方法
    handler = {
        set(target,property,value){
            target[property] = value
            if(property == 'allOperationIsDone' && value){
                //執(zhí)行閉包回調(diào)
                target.allOperationDoneBlock();
            }
            return true
         },
        get(target,property){
            return target[property]
        }
    }

    //初始化
    constructor(cb){
        this.blocks.push(cb)
        this.addObserver()
    }

    //添加觀察者
    addObserver(){
        this.proxy = new Proxy(this, this.handler)
    }

    //添加新任務(wù)
    addExecutionBlock(cb){
        this.blocks.push(cb)
    }
    
    //添加依賴
    addDependency(blockOperation){
        this.dependencyOperation = blockOperation
        blockOperation.impactOperation = this
    }

    //開始異步任務(wù)
    start(){
        const self = this
        self.isBeginStart = true
        //先判斷是否有依賴
        if(this.dependencyOperation && this.dependencyOperation.allOperationIsDone == false){
            //這里加一個定時器(目的是添加一個相對靠后的宏任務(wù)來檢查所有的任務(wù)是否都執(zhí)行了開啟,不是很嚴謹)
            setTimeout(()=>{
                if(self.dependencyOperation.isBeginStart == false){
                    throw Error('請檢查是否有依賴任務(wù)未開啟')
                }
            },0)
            //等待依賴的執(zhí)行完
            return
        }
        self.blocks.forEach((operationBlock) => {
            Promise.resolve(operationBlock).then((res)=>{
                if(res){
                    res(new Block(()=>{
                        //刪除任務(wù)
                        delete self.blocks[self.blocks.indexOf(res)]
                        //過濾null(防止delete執(zhí)行后數(shù)組中有null占位)
                        self.blocks = self.blocks.filter((item) => {
                            return item
                        })
                        //判斷是否全部完成
                        self.proxy.allOperationIsDone = (self.blocks.length == 0)
                    }))
                };
            })
        });
    }
}

四、總結(jié)與思考

其實 async / await 的使用是可以避免回調(diào)的,但是,這里并不是去用它的特性來優(yōu)化代碼,而是用 Promisethen 函數(shù)是微任務(wù)來處理異步,目的就是將一些不太重要的邏輯放到主任務(wù)之后,這里也是參考了 iOS 下的 NSBlockOperation 的一些 api 命名,語言間實現(xiàn)代碼雖然不同,但卻存在著互通的設(shè)計思路吧。

到此這篇關(guān)于封裝JS下異步任務(wù)對象的文章就介紹到這了,更多相關(guān)JS異步任務(wù)對象封裝內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • IE6-IE9中tbody的innerHTML不能賦值的解決方法

    IE6-IE9中tbody的innerHTML不能賦值的解決方法

    這篇文章主要介紹了IE6-IE9中tbody的innerHTML不能賦值的解決方法,需要的朋友可以參考下
    2014-06-06
  • 微信小程序?qū)崿F(xiàn)驗證碼獲取倒計時效果

    微信小程序?qū)崿F(xiàn)驗證碼獲取倒計時效果

    這篇文章主要為大家詳細介紹了微信小程序?qū)崿F(xiàn)驗證碼獲取倒計時效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • 淺談javascript語法和定時函數(shù)

    淺談javascript語法和定時函數(shù)

    初學(xué)者可能對Javascript的定時器有誤解,認為它們是線程,其實Javascript是運行于單線程中的,而定時器僅僅是計劃在未來的某個時間執(zhí)行,而具體的執(zhí)行時間是不能保證的,因為在頁面的生命周期中,不同的時間可能有其它代碼在控制Javascript的里進程。
    2015-05-05
  • JavaScript中統(tǒng)計Textarea字數(shù)并提示還能輸入的字符

    JavaScript中統(tǒng)計Textarea字數(shù)并提示還能輸入的字符

    是在文本框中輸入文字的時候,會自動統(tǒng)計輸入的字符,并顯示用戶還能輸入的字符,其實js也可以實現(xiàn),下面就以示例的方式為大家講解下
    2014-06-06
  • Electron實現(xiàn)應(yīng)用打包、自動升級過程解析

    Electron實現(xiàn)應(yīng)用打包、自動升級過程解析

    這篇文章主要介紹了Electron實現(xiàn)應(yīng)用打包、自動升級過程解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-07-07
  • js實現(xiàn)簡單貪吃蛇游戲

    js實現(xiàn)簡單貪吃蛇游戲

    這篇文章主要為大家詳細介紹了js實現(xiàn)簡單貪吃蛇游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • 利用iscroll4實現(xiàn)輪播圖效果實例代碼

    利用iscroll4實現(xiàn)輪播圖效果實例代碼

    iScroll 4 這個版本完全重寫了iScroll這個框架的原始代碼。這個項目的產(chǎn)生完全是因為移動版webkit瀏覽器(諸如iPhone,iPad,Android 這些系統(tǒng)上廣泛使用)。下面這篇文章主要介紹了利用iscroll4實現(xiàn)輪播圖效果的方法教程,需要的朋友可以參考下。
    2017-01-01
  • JavaScript實現(xiàn)鼠標移動事件畫筆

    JavaScript實現(xiàn)鼠標移動事件畫筆

    這篇文章主要為大家詳細介紹了JavaScript實現(xiàn)鼠標移動事件畫筆,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • javascript實現(xiàn)智能手環(huán)時間顯示

    javascript實現(xiàn)智能手環(huán)時間顯示

    這篇文章主要為大家詳細介紹了javascript實現(xiàn)智能手環(huán)時間顯示,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-09-09
  • Js中將Long轉(zhuǎn)換成日期格式的實現(xiàn)方法

    Js中將Long轉(zhuǎn)換成日期格式的實現(xiàn)方法

    這篇文章主要介紹了Js中將Long轉(zhuǎn)換成日期格式的實現(xiàn)方法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-06-06

最新評論

宜丰县| 饶河县| 安溪县| 噶尔县| 南汇区| 福鼎市| 旌德县| 黎平县| 崇信县| 湟中县| 都兰县| 甘洛县| 邓州市| 乌拉特前旗| 梁平县| 仙游县| 繁峙县| 韩城市| 江都市| 怀柔区| 宝兴县| 额尔古纳市| 格尔木市| 霞浦县| 横山县| 新化县| 青海省| 陇川县| 南陵县| 邵阳县| 乃东县| 嘉峪关市| 乌拉特前旗| 辰溪县| 姚安县| 车致| 武城县| 军事| 乌拉特中旗| 罗源县| 新民市|