摘要:異步那些事一基礎知識異步那些事二分布式事件異步那些事三異步那些事四異步那些事五異步腳本加載事件概念異步回調(diào)首先了講講中兩個方法和定義和用法方法用于在指定的毫秒數(shù)后調(diào)用函數(shù)或計算表達式。功能在事件循環(huán)的下一次循環(huán)中調(diào)用回調(diào)函數(shù)。
JS異步那些事 一 (基礎知識)
JS異步那些事 二 (分布式事件)
JS異步那些事 三 (Promise)
JS異步那些事 四(HTML 5 Web Workers)
JS異步那些事 五 (異步腳本加載)
首先了講講js中 兩個方法 setTimeout()和 setInterval()
定義和用法:setTimeout() 方法用于在指定的毫秒數(shù)后調(diào)用函數(shù)或計算表達式。語法:
setTimeout(callback,time)
callback 必需。要調(diào)用的函數(shù)后要執(zhí)行的 JavaScript 代碼串。
time 必需。在執(zhí)行代碼前需等待的毫秒數(shù)。
setInterval() 方法和setTimeout很相似,可按照指定的周期(以毫秒計)來調(diào)用函數(shù)或計算表達式。
比如上述代碼就是可以每隔1000毫秒延遲執(zhí)行timecount函數(shù),不同的是后者是周期的執(zhí)行timecount函數(shù),
SetInterval為自動重復,setTimeout不會重復。
JavaScript引擎是單線程運行的,瀏覽器無論在什么時候都只且只有一個線程在運行JavaScript程序.
執(zhí)行上述代碼,可以發(fā)現(xiàn),總的運行時間幾乎要6秒多,因為是單線程,會在while循環(huán)里面消耗5秒的時間,然后才去執(zhí)行settimeout函數(shù)。
隊列瀏覽器是基于一個事件循環(huán)的模型,在這里面,可以有多個任務隊列,比如render是一個隊列,響應用戶輸入是一個,script執(zhí)行是一個。任務隊列里放的是任務,同一個任務來源的任務肯定在同一個任務隊列里。任務有優(yōu)先級,鼠標或鍵盤響應事件優(yōu)先級高,大概是其他任務的3倍。
而我們常用的setTimeout函數(shù),其本質(zhì)上也就是向這個任務隊列添加回調(diào)函數(shù),JavaScript引擎一直等待著任務隊列中任務的到來.由于單線程關系,這些任務得進行排隊,一個接著一個被引擎處理.
如果隊列非空,引擎就從隊列頭取出一個任務,直到該任務處理完,即返回后引擎接著運行下一個任務,在任務沒返回前隊列中的其它任務是沒法被執(zhí)行的.
異步函數(shù)類型 異步IO:首先來看看很典型的一個例子 ajax
異步計時:setTimeout,setInterval都是基于事件驅(qū)動型的,通常瀏覽器不會給這個太快的速度,一般是200次/秒,效率太低了是吧如果遇到有密集型的運算的話,那就呵呵了。但是在node.js中還有process.nextTick()這個強大的東西,運行的速度將近10萬次/秒,很可觀。
process.nextTick(callback)
功能:在事件循環(huán)的下一次循環(huán)中調(diào)用 callback 回調(diào)函數(shù)。效果是將一個函數(shù)推遲到代碼書寫的下一個同步方法執(zhí)行完畢時或異步方法的事件回調(diào)函數(shù)開始執(zhí)行時;與setTimeout(fn, 0) 函數(shù)的功能類似,但它的效率高多了。
基于node.js的事件循環(huán)分析,每一次循環(huán)就是一次tick,每一次tick時,v8引擎從事件隊列中取出所有事件依次進行處理,如果遇到nextTick事件,則將其加入到事件隊尾,等待下一次tick到來時執(zhí)行;造成的結果是,nextTick事件被延遲執(zhí)行;
nextTick的確是把某任務放在隊列的最后(array.push)
nodejs在執(zhí)行任務時,會一次性把隊列中所有任務都拿出來,依次執(zhí)行
如果全部順利完成,則刪除剛才取出的所有任務,等待下一次執(zhí)行
如果中途出錯,則刪除已經(jīng)完成的任務和出錯的任務,等待下次執(zhí)行
如果第一個就出錯,則throw error
下面看一下應用場景(包含計算密集型操作,將其進行遞歸處理,而不阻塞進程):
var http = require("http"); var wait = function (mils) { var now = new Date; while (new Date - now <= mils); }; function compute() { // performs complicated calculations continuously console.log("start computing"); wait(1000); console.log("working for 1s, nexttick"); process.nextTick(compute); } http.createServer(function (req, res) { console.log("new request"); res.writeHead(200, {"Content-Type": "text/plain"}); res.end("Hello World"); }).listen(5000, "127.0.0.1"); compute();異步錯誤處理 異步異常的特點
由于js的回調(diào)異步特性,無法通過try catch來捕捉所有的異常:
try { process.nextTick(function () { foo.bar(); }); } catch (err) { //can not catch it }
而對于web服務而言,其實是非常希望這樣的:
//express風格的路由 app.get("/index", function (req, res) { try { //業(yè)務邏輯 } catch (err) { logger.error(err); res.statusCode = 500; return res.json({success: false, message: "服務器異常"}); } });
如果try catch能夠捕獲所有的異常,這樣我們可以在代碼出現(xiàn)一些非預期的錯誤時,能夠記錄下錯誤的同時,友好的給調(diào)用者返回一個500錯誤??上?,try catch無法捕獲異步中的異常。
難道我們就這樣放棄了么? 其實還有一個辦法
我們一般通過函數(shù)名傳遞的方式(引用的方式)將要執(zhí)行的操作函數(shù)傳遞給onerror事件,如
window.onerror=reportError; window.onerror=function(){alert("error")}
但我們可能不知道該事件觸發(fā)時還帶有三個默認的參數(shù),他們分別是錯誤信息,錯誤頁面的url和錯誤行號。
嵌套式回調(diào)的解嵌套
JavaScript中最常見的反模式做法是,回調(diào)內(nèi)部再嵌套回調(diào)。
這里定義了一個異步函數(shù)checkPassword,它觸發(fā)了另一個異步函數(shù)db.query,而后者又可能觸發(fā)另外一個異步函數(shù)hash。它能用,而且簡潔明了。但是,如果試圖向其添加新特性,它就會變得毛里毛躁、險象環(huán)生,比如去處理那個數(shù)據(jù)庫錯誤,而不是拋出錯誤、記錄嘗試訪問數(shù)據(jù)庫的次數(shù)、阻塞訪問數(shù)據(jù)庫,等等。
下面我們換一種寫法,雖然這種寫法很啰嗦但是可讀性更高而且更易擴展。
在平時寫嵌套時,我們應該盡量避免多層嵌套,不然中間某個地方出錯了將會導致你投入更多的時間去debug。
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://www.ezyhdfw.cn/yun/87756.html
摘要:向添加一個事件監(jiān)聽器當傳遞消息時,會執(zhí)行事件監(jiān)聽器中的代碼。終止當我們創(chuàng)建對象后,它會繼續(xù)監(jiān)聽消息即使在外部腳本完成之后直到其被終止為止。 JS異步那些事 一 (基礎知識)JS異步那些事 二 (分布式事件)JS異步那些事 三 (Promise)JS異步那些事 四(HTML 5 Web Workers)JS異步那些事 五 (異步腳本加載) 什么是 Web Worker? 當在 HTML ...
摘要:異常處理異常處理一直是回調(diào)的難題,而提供了非常方便的方法在一次調(diào)用中,任何的環(huán)節(jié)發(fā)生,都可以在最終的中捕獲到錯誤處理基本的小結具體的很多的用法可以參考阮一峰的入門教程,還有就是上面提到的電子書。 JS異步那些事 一 (基礎知識)JS異步那些事 二 (分布式事件)JS異步那些事 三 (Promise)JS異步那些事 四(HTML 5 Web Workers)JS異步那些事 五 (異步腳本...
摘要:遵循的是異步模塊定義規(guī)范,遵循的是通用模塊定義規(guī)范。不同的腳本加載這個模塊,得到的都是同一個實例。關于異步那些事就寫到這里了,很多地方理解的不夠深刻希望大家多多指教。 JS異步那些事 一 (基礎知識)JS異步那些事 二 (分布式事件)JS異步那些事 三 (Promise)JS異步那些事 四(HTML 5 Web Workers)JS異步那些事 五 (異步腳本加載) 異步腳本加載 阻塞性...
摘要:聲明的變量不得改變值,這意味著,一旦聲明變量,就必須立即初始化,不能留到以后賦值。 雖然今年沒有換工作的打算 但為了跟上時代的腳步 還是忍不住整理了一份最新前端知識點 知識點匯總 1.HTML HTML5新特性,語義化瀏覽器的標準模式和怪異模式xhtml和html的區(qū)別使用data-的好處meta標簽canvasHTML廢棄的標簽IE6 bug,和一些定位寫法css js放置位置和原因...
閱讀 1362·2021-11-22 13:54
閱讀 2501·2021-09-22 15:36
閱讀 2815·2019-08-30 15:54
閱讀 862·2019-08-30 15:53
閱讀 3225·2019-08-30 15:53
閱讀 587·2019-08-29 15:21
閱讀 2925·2019-08-28 18:28
閱讀 3107·2019-08-26 13:37