js代碼的異步執(zhí)行方式

由于JavaScript的執(zhí)行環(huán)境是單線程的,導(dǎo)致js代碼的兩種執(zhí)行方式:

  • 以js代碼的先后順序執(zhí)行的順序型
  • 以事件驅(qū)動(dòng)觸發(fā)執(zhí)行的事件型

以js代碼的先后順序執(zhí)行的順序型

也就是所謂的同步執(zhí)行,相對(duì)于位置靠前的代碼執(zhí)行完成,才去執(zhí)行后續(xù)的代碼

console.log('1');
console.log('2');

以事件驅(qū)動(dòng)觸發(fā)執(zhí)行的事件型

function c(){
    console.log('3');
}
console.log('1');
onclick = c();
console.log('2');

異步執(zhí)行:只要不阻斷js主線程執(zhí)行而執(zhí)行的代碼都是異步執(zhí)行,以上點(diǎn)擊事件觸發(fā)函數(shù)c()的執(zhí)行并不影響后續(xù)代碼執(zhí)行;所以所有的事件觸發(fā)函數(shù)都是異步執(zhí)行,也就是第一種異步執(zhí)行方式:事件監(jiān)聽

onclick = c();我們探討異步執(zhí)行的第二種方式:發(fā)布-訂閱模式:
首先onclick是js原生事件,那么換成我們自定義的事件,就構(gòu)成了所謂的發(fā)布訂閱模式,自定義事件參照自定義事件

  • 訂閱Event.on('click',fn)
  • 發(fā)布Event.emit('click')

以上我們自定義的事件click的觸發(fā)fn的執(zhí)行不影響主線程的執(zhí)行順序,所以fn函數(shù)代碼為異步執(zhí)行;從事件的發(fā)布訂閱模式,我們探討第三種異步執(zhí)行方式:回調(diào)函數(shù)

const event = {};
function on(type,callback){
     event.type = callback;
}
function emit(type){
      event.type();
}

以上就是最簡(jiǎn)單的一個(gè)事件的發(fā)布訂閱,可以看出歸根結(jié)底就是一個(gè)callback的執(zhí)行,以下是一個(gè)簡(jiǎn)單的異步回調(diào):

       function A(callback){
            console.log("I am A");
              callback();  
            console.log("I am C")
        }
        function B(){
            setTimeout(function(){
                console.log("I am B");
            },1000)
        }
        A(B);

從回調(diào)函數(shù)我們探討第四種異步執(zhí)行方式promise

        class Promisser{
            constructor(callback) {
                this.res = this.res.bind(this);
                this.rej = this.rej.bind(this);
                this.state = {};
                callback(this.res,this.rej)
            }
            res(val){
                this.state.success = val
            }
            rej(err){
                this.state.error = err
            }
            then(resCallback,rejCallback){
                Object.defineProperty(this.state,'success',{
                    get: function () {
                        return this.state
                    },
                    set: function (newValue) {
                        resCallback(newValue);
                    }
                })
                Object.defineProperty(this.state,'error',{
                    get: function () {
                        return this.state
                    },
                    set: function (newValue) {
                        rejCallback(newValue);
                    }
                })
            }
        }

        const test = new Promisser(function(res,rej){
            setTimeout(()=>{
                res('success')
            },1000)
            setTimeout(()=>{
                rej('error')
            },2000)
        })
        test.then((res)=>{
            console.log('111111',res) //111111 success
        },(rej)=>{
            console.log('222222',rej) //222222 error
        })

以上是一個(gè)簡(jiǎn)單的promiss原生模擬實(shí)現(xiàn),可以看出,歸根結(jié)底也是監(jiān)聽對(duì)應(yīng)狀態(tài)的變化觸發(fā)對(duì)應(yīng)callback的執(zhí)行,只是執(zhí)行的位置移到了函數(shù)外部;

綜上所述

js中異步執(zhí)行的方式:事件監(jiān)聽,事件的發(fā)布-訂閱,promise對(duì)的異步執(zhí)行原理都是回調(diào)函數(shù),也是js異步執(zhí)行的主要方式;

其他異步執(zhí)行方式

另外的異步執(zhí)行方式es6的新式api Generator函數(shù)與之對(duì)應(yīng)的語(yǔ)法糖async函數(shù),這里不做討論。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容