欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

廢話開篇:

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

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

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

二、實現(xiàn)效果

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

三、代碼實現(xiàn)

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

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

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

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

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

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

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

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

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

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

下面是封裝的 BlockOperation 對象

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

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

//任務對象
class BlockOperation {
    //任務集合
    blocks = []
    //是否已開始
    isBeginStart = false
    //依賴任務對象
    dependencyOperation = null
    //被依賴影響的對象
    impactOperation = null
    //全部完成的事件判定
    allOperationIsDone = false
    //全部完成的事件回調(diào)
    allOperationDoneBlock = ()=>{
        //將依賴任務完成進行自身任務
        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)
    }

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

    //開始異步任務
    start(){
        const self = this
        self.isBeginStart = true
        //先判斷是否有依賴
        if(this.dependencyOperation && this.dependencyOperation.allOperationIsDone == false){
            //這里加一個定時器(目的是添加一個相對靠后的宏任務來檢查所有的任務是否都執(zhí)行了開啟,不是很嚴謹)
            setTimeout(()=>{
                if(self.dependencyOperation.isBeginStart == false){
                    throw Error('請檢查是否有依賴任務未開啟')
                }
            },0)
            //等待依賴的執(zhí)行完
            return
        }
        self.blocks.forEach((operationBlock) => {
            Promise.resolve(operationBlock).then((res)=>{
                if(res){
                    res(new Block(()=>{
                        //刪除任務
                        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)
                    }))
                };
            })
        });
    }
}

四、總結與思考

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

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

相關文章

  • JS檢索下拉列表框中被選項目的索引號(selectedIndex)

    JS檢索下拉列表框中被選項目的索引號(selectedIndex)

    這篇文章主要介紹了JS檢索下拉列表框中被選項目的索引號(selectedIndex),本文通過實例代碼圖文詳解的形式給大家介紹的非常詳細,需要的朋友可以參考下
    2019-12-12
  • 小程序實現(xiàn)搜索框功能

    小程序實現(xiàn)搜索框功能

    這篇文章主要為大家詳細介紹了小程序實現(xiàn)搜索框功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • JavaScript的兼容性與調(diào)試技巧

    JavaScript的兼容性與調(diào)試技巧

    可能在大家使用JavaScript效果時,會碰到在各個瀏覽器中頁面的顯示效果不同,甚至報錯,這就是代碼的兼容性問題。本文就是主要介紹JavaScript的兼容性與調(diào)試技巧,希望對大家有所幫助
    2016-11-11
  • 淺析JavaScript作用域鏈、執(zhí)行上下文與閉包

    淺析JavaScript作用域鏈、執(zhí)行上下文與閉包

    JavaScript 采用詞法作用域(lexical scoping),函數(shù)執(zhí)行依賴的變量作用域是由函數(shù)定義的時候決定,而不是函數(shù)執(zhí)行的時候決定,通過本文給大家介紹JavaScript作用域鏈、執(zhí)行上下文與閉包相關知識,感興趣的朋友一起學習吧
    2016-02-02
  • 詳解JS中的快速排序與冒泡

    詳解JS中的快速排序與冒泡

    本文主要介紹了快速排序思想與冒泡排序思想。具有一定的參考價值,下面跟著小編一起來看下吧
    2017-01-01
  • js實現(xiàn)表單項的全選、反選及刪除操作示例

    js實現(xiàn)表單項的全選、反選及刪除操作示例

    這篇文章主要介紹了js實現(xiàn)表單項的全選、反選及刪除操作,結合實例形式分析了基于dedecms后臺使用js實現(xiàn)表單項的全選、反選及刪除相關操作技巧,需要的朋友可以參考下
    2020-06-06
  • 關于js復制內(nèi)容到瀏覽器剪貼板報錯:Cannot read properties of undefined (reading ‘writeText‘)的解決方案

    關于js復制內(nèi)容到瀏覽器剪貼板報錯:Cannot read properties of&n

    這篇文章主要給大家介紹了關于js復制內(nèi)容到瀏覽器剪貼板報錯:Cannot read properties of undefined (reading ‘writeText‘)的解決方案,文中給出了詳細的原因分析和解決方案,需要的朋友可以參考下
    2024-01-01
  • webpack熱更新的原理及實現(xiàn)

    webpack熱更新的原理及實現(xiàn)

    本文主要介紹了webpack熱更新的原理及實現(xiàn),,無需完全刷新整個頁面的同時,更新代碼變動的模塊,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-06-06
  • JavaScript面向對象知識串結(讀JavaScript高級程序設計(第三版))

    JavaScript面向對象知識串結(讀JavaScript高級程序設計(第三版))

    最近在看JavaScript高級程序設計(第三版),面向對象一章20多頁,來來回回看了三五遍,每次看的收獲都不一樣
    2012-07-07
  • 純js代碼生成可搜索選擇下拉列表的實例

    純js代碼生成可搜索選擇下拉列表的實例

    下面小編就為大家分享一篇純js代碼生成可搜索選擇下拉列表的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01

最新評論