成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

javascript異步編程總結(jié)

yearsj / 2548人閱讀

摘要:以下總結(jié)了異步編程的種方式回調(diào)函數(shù)回調(diào)函數(shù)異步編程的最基本的方式。由小組的成員在規(guī)范中提出,目的是為異步編程提供統(tǒng)一接口。結(jié)尾參考文章異步編程參考文章使用詳解

前言

Javascript語言的執(zhí)行環(huán)境是“單線程”。

單線程: 一次只能完成一個(gè)任務(wù)。如果有多個(gè)任務(wù),就必須排隊(duì),前面一個(gè)任務(wù)完成,再執(zhí)行后面一個(gè)任務(wù)。

單線程的好處是執(zhí)行環(huán)境簡(jiǎn)單,壞處是在一些耗時(shí)的任務(wù)上會(huì)堵塞進(jìn)程。比如讀取一個(gè)大文件,線程卡在這個(gè)任務(wù)上,造成頁面卡死。

那如何在讀取文件的同時(shí),又能查看圖片,做一些其他的事呢?

這就到了“同步”和“異步”之爭(zhēng):
同步:后一個(gè)任務(wù)等待前一個(gè)任務(wù)結(jié)束,然后再執(zhí)行,程序的執(zhí)行順序與任務(wù)的排列順序是一致的、同步的。
異步:每一個(gè)任務(wù)有一個(gè)或多個(gè)回調(diào)函數(shù)(callback),前一個(gè)任務(wù)結(jié)束后,不是執(zhí)行后一個(gè)任務(wù),而是執(zhí)行回調(diào)函數(shù),后一個(gè)任務(wù)則是不等前一個(gè)任務(wù)結(jié)束就執(zhí)行,所以程序的執(zhí)行順序與任務(wù)的排列順序是不一致的、異步的。

舉個(gè)栗子:
去餐廳吃飯
同步:大家依次排隊(duì),前一個(gè)人付完錢,等待領(lǐng)取食物。。。漫長(zhǎng)等待。。。食物做好了,后一個(gè)人跟進(jìn)。
異步:大家依次排隊(duì),前一個(gè)人付完錢,服務(wù)員給他一個(gè)餐牌,后一個(gè)人跟進(jìn)。餐牌對(duì)應(yīng)的食物做好了,再去領(lǐng)取。

以下總結(jié)了“異步編程”的4種方式:

1. 回調(diào)函數(shù)

回調(diào)函數(shù):異步編程的最基本的方式。

下面通過樣例作為演示:我們定義三個(gè)方法“做飯”(cook)、“吃飯”(eat),“洗碗”(wash)三個(gè)方法,它們是層層依賴的關(guān)系,下一步的的操作需要使用上一部操作的結(jié)果(這里使用 setTimeout 模擬異步操作)。

// 做飯
function cook() {
    console.log("開始做飯...");

    sleep(2000);   // 等待2秒

    console.log("做飯完畢");
}

// 吃飯
function eat() {
    console.log("開始吃飯...");

    sleep(2000);   // 等待2秒

    console.log("吃飯完畢");
}

// 洗碗
function wash() {
    console.log("開始洗碗...");

    sleep(2000);   // 等待2秒

    console.log("洗碗完畢");
}

// 阻塞等待(毫秒)
function sleep(delay) {
    let start = (new Date()).getTime();

    while((new Date()).getTime() - start < delay) {
        continue;
    }
}

cook();
eat();
wash();

// 開始做飯...
// 做飯完畢
// 開始吃飯...
// 吃飯完畢
// 開始洗碗...
// 洗碗完畢

上面是“同步”的寫法,下面我們改寫成“異步”:回調(diào)函數(shù)

// 做飯
function cook(callback) {
    console.log("開始做飯...");

    setTimeout(function() {
        console.log("做飯完畢");

        // 這里是回調(diào),執(zhí)行吃飯的方法
        callback();

    }, 2000);
}

// 吃飯
function eat(callback) {
    console.log("開始吃飯...");

    setTimeout(function() {
        console.log("吃飯完畢");

        // 這里是回調(diào),執(zhí)行洗碗的方法
        callback();
        
    }, 2000);
}

// 洗碗
function wash() {
    console.log("開始洗碗...");

    setTimeout(function() {
        console.log("洗碗完畢");

        // 洗碗之后的其他動(dòng)作,這里就不寫了

    }, 2000);
}

cook(function() {
    eat(function() {
        wash();
    })
});

// 開始做飯...
// 做飯完畢
// 開始吃飯...
// 吃飯完畢
// 開始洗碗...
// 洗碗完畢

回調(diào)函數(shù)的優(yōu)點(diǎn)是簡(jiǎn)單、容易理解和部署,缺點(diǎn)是不利于代碼的閱讀和維護(hù),各個(gè)部分之間高度耦合(Coupling),流程會(huì)很混亂,而且每個(gè)任務(wù)只能指定一個(gè)回調(diào)函數(shù)。

2. 事件監(jiān)聽

事件監(jiān)聽:采用事件驅(qū)動(dòng)模式,任務(wù)的執(zhí)行不取決于代碼的順序,而取決于某個(gè)事件是否發(fā)生。

let events = require("events");
let eventEmitter = new events.EventEmitter();

// 做飯
var cook = function() {
    console.log("開始做飯...");

    setTimeout(function() {
        console.log("做飯完畢");

        // 執(zhí)行eat事件
        eventEmitter.emit("eatEvent");

    }, 2000);
}

// 吃飯
var eat = function() {
    console.log("開始吃飯...");

    setTimeout(function() {
        console.log("吃飯完畢");

        // 執(zhí)行wash事件
        eventEmitter.emit("washEvent");

    }, 2000);
}

// 洗碗
var wash = function() {
    console.log("開始洗碗...");

    setTimeout(function() {
        console.log("洗碗完畢");

        // 洗碗之后的其他動(dòng)作,這里就不寫了

    }, 2000);
}

// 綁定cook事件
eventEmitter.on("cookEvent", cook);
// 綁定eat事件
eventEmitter.on("eatEvent", eat);
// 綁定wash事件
eventEmitter.on("washEvent", wash);

// 執(zhí)行cook事件
eventEmitter.emit("cookEvent");

// 開始做飯...
// 做飯完畢
// 開始吃飯...
// 吃飯完畢
// 開始洗碗...
// 洗碗完畢

這種方法的優(yōu)點(diǎn)是比較容易理解,可以綁定多個(gè)事件,每個(gè)事件可以指定多個(gè)回調(diào)函數(shù),而且可以"去耦合"(Decoupling),有利于實(shí)現(xiàn)模塊化。缺點(diǎn)是整個(gè)程序都要變成事件驅(qū)動(dòng)型,運(yùn)行流程會(huì)變得很不清晰

3. 發(fā)布/訂閱

發(fā)布/訂閱:又稱“觀察者模式”。我們假定,存在一個(gè)"信號(hào)中心",某個(gè)任務(wù)執(zhí)行完成,就向信號(hào)中心"發(fā)布"(publish)一個(gè)信號(hào),其他任務(wù)可以向信號(hào)中心"訂閱"(subscribe)這個(gè)信號(hào),從而知道什么時(shí)候自己可以開始執(zhí)行。

和上一個(gè)“事件監(jiān)聽”很類似,本人對(duì)這種模式理解有限,這里就不列代碼誤導(dǎo)大家了。

4. Promise

Promise: 由 CommonJS 小組的成員在 Promise/A 規(guī)范中提出,目的是為異步編程提供統(tǒng)一接口。

根據(jù) Promise/A 規(guī)范,promise 是一個(gè)對(duì)象,只需要 then 這一個(gè)方法。

// 做飯
function cook() {
    console.log("開始做飯...");

    let promise = new Promise(function(resolve, reject) {
        setTimeout(function() {
            console.log("做飯完畢");
    
            resolve();
    
        }, 2000);
    });

    return promise;
}

// 吃飯
function eat(callback) {
    console.log("開始吃飯...");

    let promise = new Promise(function(resolve, reject) {
        setTimeout(function() {
            console.log("吃飯完畢");
    
            resolve();
            
        }, 2000);
    });

    return promise;
}

// 洗碗
function wash() {
    console.log("開始洗碗...");

    let promise = new Promise(function(resolve, reject) {
        setTimeout(function() {
            console.log("洗碗完畢");
    
            // 洗碗之后的其他動(dòng)作,這里就不寫了
            resolve();
    
        }, 2000);
    });

    return promise;
}

cook()
.then(function() {
    return eat();
})
.then(function() {
    return wash();
})
.then(function() {
    console.log("結(jié)束...");
})
.catch(function() {
    console.log("好像出什么問題了"); 
});

優(yōu)點(diǎn):

回調(diào)函數(shù)變成了鏈?zhǔn)綄懛?,程序的流程可以看得很清楚,而且有一整套的配套方法,可以?shí)現(xiàn)許多強(qiáng)大的功能。解決回調(diào)地獄(Callback Hell)問題

更好地進(jìn)行錯(cuò)誤捕獲

Promise的功能不僅僅只上面用到的,諸如其他all(), race()之類,限于篇幅,大家可以翻看其他文章查看。

結(jié)尾

參考文章:Javascript異步編程
參考文章:Promise使用詳解

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/102916.html

相關(guān)文章

  • ES6-7

    摘要:的翻譯文檔由的維護(hù)很多人說,阮老師已經(jīng)有一本關(guān)于的書了入門,覺得看看這本書就足夠了。前端的異步解決方案之和異步編程模式在前端開發(fā)過程中,顯得越來越重要。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。 JavaScript Promise 迷你書(中文版) 超詳細(xì)介紹promise的gitbook,看完再不會(huì)promise...... 本書的目的是以目前還在制定中的ECMASc...

    mudiyouyou 評(píng)論0 收藏0
  • 前端排序算法總結(jié);前端面試題2.0;JavaScript異步編程

    摘要:與異步編程按照維基百科上的解釋獨(dú)立于主控制流之外發(fā)生的事件就叫做異步。因?yàn)榈拇嬖?,至少在被?biāo)準(zhǔn)化的那一刻起,就支持異步編程了。然而異步編程真正發(fā)展壯大,的流行功不可沒。在握手過程中,端點(diǎn)交換認(rèn)證和密鑰以建立或恢復(fù)安全會(huì)話。 1、前端 排序算法總結(jié) 排序算法可能是你學(xué)編程第一個(gè)學(xué)習(xí)的算法,還記得冒泡嗎? 當(dāng)然,排序和查找兩類算法是面試的熱門選項(xiàng)。如果你是一個(gè)會(huì)寫快排的程序猿,面試官在比較...

    aaron 評(píng)論0 收藏0
  • 前端排序算法總結(jié);前端面試題2.0;JavaScript異步編程

    摘要:與異步編程按照維基百科上的解釋獨(dú)立于主控制流之外發(fā)生的事件就叫做異步。因?yàn)榈拇嬖冢辽僭诒粯?biāo)準(zhǔn)化的那一刻起,就支持異步編程了。然而異步編程真正發(fā)展壯大,的流行功不可沒。在握手過程中,端點(diǎn)交換認(rèn)證和密鑰以建立或恢復(fù)安全會(huì)話。 1、前端 排序算法總結(jié) 排序算法可能是你學(xué)編程第一個(gè)學(xué)習(xí)的算法,還記得冒泡嗎? 當(dāng)然,排序和查找兩類算法是面試的熱門選項(xiàng)。如果你是一個(gè)會(huì)寫快排的程序猿,面試官在比較...

    ARGUS 評(píng)論0 收藏0
  • 前端排序算法總結(jié);前端面試題2.0;JavaScript異步編程

    摘要:與異步編程按照維基百科上的解釋獨(dú)立于主控制流之外發(fā)生的事件就叫做異步。因?yàn)榈拇嬖?,至少在被?biāo)準(zhǔn)化的那一刻起,就支持異步編程了。然而異步編程真正發(fā)展壯大,的流行功不可沒。在握手過程中,端點(diǎn)交換認(rèn)證和密鑰以建立或恢復(fù)安全會(huì)話。 1、前端 排序算法總結(jié) 排序算法可能是你學(xué)編程第一個(gè)學(xué)習(xí)的算法,還記得冒泡嗎? 當(dāng)然,排序和查找兩類算法是面試的熱門選項(xiàng)。如果你是一個(gè)會(huì)寫快排的程序猿,面試官在比較...

    April 評(píng)論0 收藏0
  • javascript基礎(chǔ)總結(jié)(二)——異步編程情況

    摘要:異步規(guī)定要做一件事,不是立馬執(zhí)行這件事,需要等一定的時(shí)間,這樣的話,我們不會(huì)等著它執(zhí)行,而是繼續(xù)執(zhí)行下面的操作,只有將下面的事情處理完了,才會(huì)返回頭處理之前的事情如果下面的事情并沒有處理完成,不管之前的事情有沒有到時(shí)間,都踏踏實(shí)實(shí)的給我等著 異步:規(guī)定要做一件事,不是立馬執(zhí)行這件事,需要等一定的時(shí)間,這樣的話,我們不會(huì)等著它執(zhí)行,而是繼續(xù)執(zhí)行下面的操作,只有將下面的事情處理完了,才會(huì)返...

    Dionysus_go 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<