亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

廢話開篇:

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

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

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

二、實(shí)現(xiàn)效果

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

三、代碼實(shí)現(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ù)完成進(jìn)行自身任務(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){
            //這里加一個(gè)定時(shí)器(目的是添加一個(gè)相對靠后的宏任務(wù)來檢查所有的任務(wù)是否都執(zhí)行了開啟,不是很嚴(yán)謹(jǐn))
            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é)與思考

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

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

相關(guān)文章

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

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

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

    小程序?qū)崿F(xiàn)搜索框功能

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

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

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

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

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

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

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

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

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

    關(guān)于js復(fù)制內(nèi)容到瀏覽器剪貼板報(bào)錯(cuò):Cannot read properties of&n

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

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

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

    JavaScript面向?qū)ο笾R串結(jié)(讀JavaScript高級程序設(shè)計(jì)(第三版))

    最近在看JavaScript高級程序設(shè)計(jì)(第三版),面向?qū)ο笠徽?0多頁,來來回回看了三五遍,每次看的收獲都不一樣
    2012-07-07
  • 純js代碼生成可搜索選擇下拉列表的實(shí)例

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

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

最新評論