填坑十萬個為什麼?(19)

NO IMAGE

簡介:很多概念不清或忘記,重新構建自己的知識體系。每天問自己1~多個問題。我是菜鳥 成為大神之路!

1.什麼是異步操作?異步操作有哪些?

JS因為是單線程的,所以在執行事務的時候,往往會因為某個事務的延遲,而導致服務器假死,這時候異步編程就顯的格外重要,但是異步編程一般理解為回調函數callback,典型的就是node,回調函數的層層嵌套又導致程序過於冗餘,因為閉包的存在,導致了內存的洩露或者誤改上一層回調函數的參數

①回調函數
`在f1執行完之後再執行f2`
var func1=function(callback){
    console.log(1);
    (callback && typeof(callback)==='function') && callback();
}
func1(func2);
var func2=function(){
    console.log(2);
}

`Ajax`
$.ajax({
    url:"/getmsg",
    type: 'GET',
    dataType: 'json',
    success: function(ret) {
        if (ret && ret.status) {
            //
        }
    },
    error: function(xhr) {
        //
    }
})
②事件監聽

通過事件機制,實現代碼的解耦。js處理DOM交互就是採用的事件機制,我們這兒只是實現一些自定義的事件而已。JS中已經很好的支持了自定義事件,如:

//新建一個事件
var event=new Event('Popup::Show');
//dispatch the event
elem1.dispatchEvent(event)

//listen for this event
elem2.addEventListener('Popup::Show',function(msg){},false)

`添加事件監聽的方法`
element.addEventListener('click', funEven, false);
element.attachEvent('onclick', funEven);
element.onclick = funEven;
第14天的內容 https://juejin.im/post/5c28761b5188250baa55bcb7
③ 觀察者模式,也叫訂閱發佈模式

多個觀察者可以訂閱同一個主題,主題對象改變時,主題對象就會通知這個觀察者
其中步驟包括,訂閱、發佈、退訂;先訂閱(subscribe)一個主題對象,根據主題對象發佈(publish)內容,期間也退訂(unsubscribe)主題對象,一旦退訂就無法再次發佈
可以把訂閱一個主題對象理解成監聽一個事件
觀察者模式的一個特點就是一旦主題事件一改變,就會通知整個觀察者;觀察者模式還可以計算出訂閱事件的個數

//發佈-訂閱
//有個消息池,存放所有消息
let pubsub = {};
(function(myObj) {
    topics = {}
    subId = -1;
    //發佈者接受參數(消息名稱,參數)
    myObj.publish = function(topic, msg) {
            //如果發佈的該消息沒有訂閱者,直接返回
            if (!topics[topic]) {
                return
            }
            //對該消息的所有訂閱者,遍歷去執行各自的回調函數
            let subs = topics[topic]
            subs.forEach(function(sub) {
                sub.func(topic, msg)
            })
        }
    //訂閱者接受參數:(消息名稱,回調函數)
    myObj.subscribe = function(topic, func) {
        //如果訂閱的該事件還未定義,初始化
        if (!topics[topic]) {
            topics[topic] = []
        }
        //使用不同的token來作為訂閱者的索引
        let token = (++subId).toString()
        topics[topic].push({
                token: token,
                func: func
            })
        return token
    }
    myObj.unsubscribe = function(token) {
        //對消息列表遍歷查找該token是哪個消息中的哪個訂閱者
        for (let t in topics) {
            //如果某個消息沒有訂閱者,直接返回
            if (!topics[t]) {
                return }
            topics[t].forEach(function(sub,index) {
                if (sub.token === token) {
                    //找到了,從訂閱者的數組中去掉該訂閱者
                    topics[t].splice(index, 1)
                }
            })
        }
    }
})(pubsub)

let sub1 = pubsub.subscribe('Msg::Name', function(topic, msg) {
    console.log("event is :" + topic + "; data is :" + msg)
});
let sub2 = pubsub.subscribe('Msg::Name', function(topic, msg) {
    console.log("this is another subscriber, data is :" + msg)
});
pubsub.publish('Msg::Name', '123')

pubsub.unsubscribe(sub2)
pubsub.publish('Msg::Name', '456')

④promise

第18天的內容 juejin.im/post/5c2dd2…

⑤Generator函數

第20天學習

⑥es7語法糖async/await

第20天學習

文章推薦
JS中的異步操作
JS進階 | 分析JS中的異步操作

相關文章

填坑十萬個為什麼?(23)

填坑十萬個為什麼?(22)

填坑十萬個為什麼?(21)

填坑十萬個為什麼?(20)