国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

淺析JavaScript異步

Tangpj / 1156人閱讀

摘要:回調(diào)函數(shù),一般在同步情境下是最后執(zhí)行的,而在異步情境下有可能不執(zhí)行,因為事件沒有被觸發(fā)或者條件不滿足。同步方式請求異步同步請求當(dāng)請求開始發(fā)送時,瀏覽器事件線程通知主線程,讓線程發(fā)送數(shù)據(jù)請求,主線程收到

一直以來都知道JavaScript是一門單線程語言,在筆試過程中不斷的遇到一些輸出結(jié)果的問題,考量的是對異步編程掌握情況。一般被問到異步的時候腦子里第一反應(yīng)就是AjaxsetTimseout...這些東西。在平時做項目過程中,基本大多數(shù)操作都是異步的。JavaScript異步都是通過回調(diào)形式完成的,開發(fā)過程中一直在處理回調(diào),可能不知不覺中自己就已經(jīng)處在回調(diào)地獄中。

瀏覽器線程

在開始之前簡單的說一下瀏覽器的線程,對瀏覽器的作業(yè)有個基礎(chǔ)的認(rèn)識。之前說過JavaScript是單線程作業(yè),但是并不代表瀏覽器就是單線程的。

JavaScript引擎中負(fù)責(zé)解析和執(zhí)行JavaScript代碼的線程只有一個。但是除了這個主進程以外,還有其他很多輔助線程。那么諸如onclick回調(diào),setTimeoutAjax這些都是怎么實現(xiàn)的呢?即瀏覽器搞了幾個其他線程去輔助JavaScript線程的運行。

瀏覽器有很多線程,例如:

GUI渲染線程 - GUI渲染線程處于掛起狀態(tài)的,也就是凍結(jié)狀態(tài)

JavaScript引擎線程 - 用于解析JavaScript代碼

定時器觸發(fā)線程 - 瀏覽器定時計數(shù)器并不是 js引擎計數(shù)

瀏覽器事件線程 - 用于解析BOM渲染等工作

http線程 - 主要負(fù)責(zé)數(shù)據(jù)請求

EventLoop輪詢處理線程 - 事件被觸發(fā)時該線程會把事件添加到待處理隊列的隊尾

等等等

從上面來看可以得出,瀏覽器其實也做了很多事情,遠(yuǎn)遠(yuǎn)的沒有想象中的那么簡單,上面這些線程中GUI渲染線程,JavaScript引擎線程,瀏覽器事件線程是瀏覽器的常駐線程。

當(dāng)瀏覽器開始解析代碼的時候,會根據(jù)代碼去分配給不同的輔助線程去作業(yè)。

進程

進程是指在操作系統(tǒng)中正在運行的一個應(yīng)用程序

線程

線程是指進程內(nèi)獨立執(zhí)行某個任務(wù)的一個單元。線程自己基本上不擁有系統(tǒng)資源,只擁有一點在運行中必不可少的資源(如程序計數(shù)器,一組寄存器和棧)。

進程中包含線程,一個進程中可以有N個進程。我們可以在電腦的任務(wù)管理器中查看到正在運行的進程,可以認(rèn)為一個進程就是在運行一個程序,比如用瀏覽器打開一個網(wǎng)頁,這就是開啟了一個進程。但是比如打開3個瀏覽器,那么就開啟了3個進程。

同步&異步

既然要了解同步異步當(dāng)然要簡單的說一下同步和異步。說到同步和異步最有發(fā)言權(quán)的真的就屬Ajax了,為了讓例子更加明顯沒有使用Ajax舉例。(●ˇ?ˇ●)

同步

同步會逐行執(zhí)行代碼,會對后續(xù)代碼造成阻塞,直至代碼接收到預(yù)期的結(jié)果之后,才會繼續(xù)向下執(zhí)行。

console.log(1);
alert("同步");
console.log(2);

//  結(jié)果:
//  1
//  同步
//  2

異步

如果在函數(shù)返回的時候,調(diào)用者還不能夠得到預(yù)期結(jié)果,而是將來通過一定的手段得到結(jié)果(例如回調(diào)函數(shù)),這就是異步。

console.log(1);
setTimeout(() => {
   alert("異步"); 
},0);
console.log(2);

//  結(jié)果:
//  1
//  2
//  異步
為什么JavaScript要采用異步編程

一開始就說過,JavaScript是一種單線程執(zhí)行的腳本語言(這可能是由于歷史原因或為了簡單而采取的設(shè)計)。它的單線程表現(xiàn)在任何一個函數(shù)都要從頭到尾執(zhí)行完畢之后,才會執(zhí)行另一個函數(shù),界面的更新、鼠標(biāo)事件的處理、計時器(setTimeout、setInterval等)的執(zhí)行也需要先排隊,后串行執(zhí)行。假如有一段JavaScript從頭到尾執(zhí)行時間比較長,那么在執(zhí)行期間任何UI更新都會被阻塞,界面事件處理也會停止響應(yīng)。這種情況下就需要異步編程模式,目的就是把代碼的運行打散或者讓IO調(diào)用(例如AJAX)在后臺運行,讓界面更新和事件處理能夠及時地運行。

JavaScript語言的設(shè)計者意識到,這時主線程完全可以不管IO設(shè)備,掛起處于等待中的任務(wù),先運行排在后面的任務(wù)。等到IO設(shè)備返回了結(jié)果,再回過頭,把掛起的任務(wù)繼續(xù)執(zhí)行下去。

異步運行機制:

所有同步任務(wù)都在主線程上執(zhí)行,形成一個執(zhí)行棧。

主線程之外,還存在一個任務(wù)隊列。只要異步任務(wù)有了運行結(jié)果,就在任務(wù)隊列之中放置一個事件。

一旦執(zhí)行棧中的所有同步任務(wù)執(zhí)行完畢,系統(tǒng)就會讀取任務(wù)隊列,看看里面有哪些事件。那些對應(yīng)的異步任務(wù),于是結(jié)束等待狀態(tài),進入執(zhí)行棧,開始執(zhí)行。

主線程不斷重復(fù)上面的第三步。

舉個例子:



點擊同步按鈕會調(diào)用updateSync的同步函數(shù),邏輯非常簡單,循環(huán)體內(nèi)每次更新output結(jié)點的內(nèi)容為i。如果在其他多線程模型下的語言,你可能會看到界面上以非常快的速度顯示從0999999后停止。但是在JavaScript中,你會感覺按鈕按下去的時候卡了一下,然后看到一個最終結(jié)果999999,而沒有中間過程,這就是因為在updateSync函數(shù)運行過程中UI更新被阻塞,只有當(dāng)它結(jié)束退出后才會更新UI。反之,當(dāng)點擊異步的時候,會明顯的看到Dom在逐步更新的過程。

從上面的例子中可以明顯的看出,異步編程對于JavaScript來說是多么多么的重要。

異步編程有什么好處

從編程方式來講當(dāng)然是同步編程的方式更為簡單,但是同步有其局限性一是假如是單線程那么一旦遇到阻塞調(diào)用,會造成整個線程阻塞,導(dǎo)致cpu無法得到有效利用,而瀏覽器的JavaScript執(zhí)行和瀏覽器渲染是運行在單線程中,一旦遇到阻塞調(diào)用不僅意味JavaScript的執(zhí)行被阻塞更意味整個瀏覽器渲染也被阻塞這就導(dǎo)致界面的卡死,若是多線程則不可避免的要考慮互斥和同步問題,而互斥和同步帶來復(fù)雜度也很大,實際上瀏覽器下因為同時只能執(zhí)行一段JavaScript代碼這意味著不存在互斥問題,但是同步問題仍然不可避免,以往回調(diào)風(fēng)格中異步的流程控制(其實就是同步問題)也比較復(fù)雜。瀏覽器端的編程方式也即是GUI編程,其本質(zhì)就是事件驅(qū)動的(鼠標(biāo)點擊,Http請求結(jié)束等)異步編程更為自然。

突然有個疑問,既然如此為什么JavaScript沒有使用多線程作業(yè)呢?就此就去Google了一下JavaScript多線程,在HTML5推出之后是提供了多線程只是比較局限。在使用多線程的時候無法使用window對象。若JavaScript使用多線程,在A線程中正在操作DOM,但是B線程中已經(jīng)把該DOM已經(jīng)刪除了(只是簡單的小栗子,可能還有很多問題,至于這些歷史問題無從考究了)。會給編程作業(yè)帶來很大的負(fù)擔(dān)。就我而言我想這也就說明了為什么JavaScript沒有使用多線程的原因吧。

異步與回調(diào)

回調(diào)到底屬于異步么?會想起剛剛開始學(xué)習(xí)JavaScript的時候常常吧這兩個概念混合在一起。在搞清楚這個問題,首先要明白什么是回調(diào)函數(shù)。

百科:回調(diào)函數(shù)是一個函數(shù),它作為參數(shù)傳遞給另一個函數(shù),并在父函數(shù)完成后執(zhí)行。回調(diào)的特殊之處在于,出現(xiàn)在“父類”之后的函數(shù)可以在回調(diào)執(zhí)行之前執(zhí)行。另一件需要知道的重要事情是如何正確地傳遞回調(diào)。這就是我經(jīng)常忘記正確語法的地方。

通過上面的解釋可以得出,回調(diào)函數(shù)本質(zhì)上其實就是一種設(shè)計模式,例如我們熟悉的JQuery也只不過是遵循了這個設(shè)計原則而已。在JavaScript中,回調(diào)函數(shù)具體的定義為:函數(shù)A作為參數(shù)(函數(shù)引用)傳遞到另一個函數(shù)B中,并且這個函數(shù)B執(zhí)行函數(shù)A。我們就說函數(shù)A叫做回調(diào)函數(shù)。如果沒有名稱(函數(shù)表達式),就叫做匿名回調(diào)函數(shù)。

簡單的舉個小例子:

function test (n,fn){
    console.log(n);
    fn && fn(n);
}
console.log(1);
test(2);
test(3,function(n){
    console.log(n+1)
});
console.log(5)

//  結(jié)果
//  1
//  2
//  3
//  4
//  5

通過上面的代碼輸出的結(jié)果可以得出回調(diào)函數(shù)不一定屬于異步,一般同步會阻塞后面的代碼,通過輸出結(jié)果也就得出了這個結(jié)論。回調(diào)函數(shù),一般在同步情境下是最后執(zhí)行的,而在異步情境下有可能不執(zhí)行,因為事件沒有被觸發(fā)或者條件不滿足。

回調(diào)函數(shù)應(yīng)用場景

資源加載:動態(tài)加載js文件后執(zhí)行回調(diào),加載iframe后執(zhí)行回調(diào),ajax操作回調(diào),圖片加載完成執(zhí)行回調(diào),AJAX等等。

DOM事件及Node.js事件基于回調(diào)機制(Node.js回調(diào)可能會出現(xiàn)多層回調(diào)嵌套的問題)。

setTimeout的延遲時間為0,這個hack經(jīng)常被用到,settimeout調(diào)用的函數(shù)其實就是一個callback的體現(xiàn)

鏈?zhǔn)秸{(diào)用:鏈?zhǔn)秸{(diào)用的時候,在賦值器(setter)方法中(或者本身沒有返回值的方法中)很容易實現(xiàn)鏈?zhǔn)秸{(diào)用,而取值器(getter)相對來說不好實現(xiàn)鏈?zhǔn)秸{(diào)用,因為你需要取值器返回你需要的數(shù)據(jù)而不是this指針,如果要實現(xiàn)鏈?zhǔn)椒椒ǎ梢杂没卣{(diào)函數(shù)來實現(xiàn)。

setTimeout、setInterval的函數(shù)調(diào)用得到其返回值。由于兩個函數(shù)都是異步的,即:調(diào)用時序和程序的主流程是相對獨立的,所以沒有辦法在主體里面等待它們的返回值,它們被打開的時候程序也不會停下來等待,否則也就失去了setTimeout及setInterval的意義了,所以用return已經(jīng)沒有意義,只能使用callback。callback的意義在于將timer執(zhí)行的結(jié)果通知給代理函數(shù)進行及時處理。

JavaScript中的那些異步操作

JavaScript既然有很多的輔助線程,不可能所有的工作都是通過主線程去做,既然分配給輔助線程去做事情。

XMLHttpRequest

XMLHttpRequest對象應(yīng)該不是很陌生的,主要用于瀏覽器的數(shù)據(jù)請求與數(shù)據(jù)交互。XMLHttpRequest對象提供兩種請求數(shù)據(jù)的方式,一種是同步,一種是異步。可以通過參數(shù)進行配置。默認(rèn)為異步。

對于XMLHttpRequest這里就不作太多的贅述了。

var xhr = new XMLHttpRequest();
xhr.open("GET", url, false);    //同步方式請求 
xhr.open("GET", url, true);     //異步
xhr.send();

同步Ajax請求:

當(dāng)請求開始發(fā)送時,瀏覽器事件線程通知主線程,讓Http線程發(fā)送數(shù)據(jù)請求,主線程收到請求之后,通知Http線程發(fā)送請求,Http線程收到主線程通知之后就去請求數(shù)據(jù),等待服務(wù)器響應(yīng),過了N年之后,收到請求回來的數(shù)據(jù),返回給主線程數(shù)據(jù)已經(jīng)請求完成,主線程把結(jié)果返回給了瀏覽器事件線程,去完成后續(xù)操作。

異步Ajax請求:

當(dāng)請求開始發(fā)送時,瀏覽器事件線程通知,瀏覽器事件線程通知主線程,讓Http線程發(fā)送數(shù)據(jù)請求,主線程收到請求之后,通知Http線程發(fā)送請求,Http線程收到主線程通知之后就去請求數(shù)據(jù),并通知主線程請求已經(jīng)發(fā)送,主進程通知瀏覽器事件線程已經(jīng)去請求數(shù)據(jù),則
瀏覽器事件線程,只需要等待結(jié)果,并不影響其他工作。

setInterval&setTimeout

setIntervalsetTimeout同屬于異步方法,其異步是通過回調(diào)函數(shù)方式實現(xiàn)。其兩者的區(qū)別則setInterval會連續(xù)調(diào)用回調(diào)函數(shù),則setTimeout會延時調(diào)用回調(diào)函數(shù)只會執(zhí)行一次。

setInterval(() => {
    alert(1)
},2000)
//  每隔2s彈出一次1
setTimeout(() => {
    alert(2)
},2000)
//  進入頁面后2s彈出2,則不會再次彈出

requestAnimationFarme

requestAnimationFrame字面意思就是去請求動畫幀,在沒有API之前都是基于setInterval,與setInterval相比,requestAnimationFrame最大的優(yōu)勢是由系統(tǒng)來決定回調(diào)函數(shù)的執(zhí)行時機。具體一點講,如果屏幕刷新率是60Hz,那么回調(diào)函數(shù)就每16.7ms被執(zhí)行一次,如果刷新率是75Hz,那么這個時間間隔就變成了1000/75=13.3ms,換句話說就是,requestAnimationFrame的步伐跟著系統(tǒng)的刷新步伐走。它能保證回調(diào)函數(shù)在屏幕每一次的刷新間隔中只被執(zhí)行一次,這樣就不會引起丟幀現(xiàn)象,也不會導(dǎo)致動畫出現(xiàn)卡頓的問題。

舉個小例子:

var progress = 0;
//回調(diào)函數(shù)
function render() {
    progress += 1; //修改圖像的位置
    if (progress < 100) {
        //在動畫沒有結(jié)束前,遞歸渲染
        window.requestAnimationFrame(render);
    }
}
//第一幀渲染
window.requestAnimationFrame(render);

Object.observe - 觀察者

Object.observe是一個提供數(shù)據(jù)監(jiān)視的API,在chrome中已經(jīng)可以使用。是ECMAScript 7 的一個提案規(guī)范,官方建議的是謹(jǐn)慎使用級別,但是個人認(rèn)為這個API非常有用,例如可以對現(xiàn)在流行的MVVM框架作一些簡化和優(yōu)化。雖然標(biāo)準(zhǔn)還沒定,但是標(biāo)準(zhǔn)往往是滯后于實現(xiàn)的,只要是有用的東西,肯定會有越來越多的人去使用,越來越多的引擎會支持,最終促使標(biāo)準(zhǔn)的生成。從observe字面意思就可以知道,這玩意兒就是用來做觀察者模式之類。

var obj = {a: 1};
Object.observe(obj, output);
obj.b = 2;
obj.a = 2;
Object.defineProperties(obj, {a: { enumerable: false}}); //修改屬性設(shè)定
delete obj.b;
function output(change) {
    console.log(1)
}

Promise

Promise是對異步編程的一種抽象。它是一個代理對象,代表一個必須進行異步處理的函數(shù)返回的值或拋出的異常。也就是說Promise對象代表了一個異步操作,可以將異步對象和回調(diào)函數(shù)脫離開來,通過then方法在這個異步操作上面綁定回調(diào)函數(shù)。

在Promise中最直觀的例子就是Promise.all統(tǒng)一去請求,返回結(jié)果。

var p1 = Promise.resolve(3);
var p2 = 42;
var p3 = new Promise(function(resolve, reject) {
  setTimeout(resolve, 100, "foo");
});
Promise.all([p1, p2, p3]).then(function(values) {
  console.log(values);
});
// expected output: Array [3, 42, "foo"]

Generator&Async/Await

ES6Generator卻給異步操作又提供了新的思路,馬上就有人給出了如何用Generator來更加優(yōu)雅的處理異步操作。Generator函數(shù)是協(xié)程在ES6的實現(xiàn),最大特點就是可以交出函數(shù)的執(zhí)行權(quán)(即暫停執(zhí)行)。整個Generator函數(shù)就是一個封裝的異步任務(wù),或者說是異步任務(wù)的容器。異步操作需要暫停的地方,都用yield語句注明。Generator函數(shù)的執(zhí)行方法如下。

function * greneratorDome(){
    yield "Hello";
    yield "World";
    return "Ending";
}
let grenDome = greneratorDome();
console.log(grenDome.next());
// {value: "Hello", done: false}
console.log(grenDome.next());
// {value: "World", done: false}
console.log(grenDome.next());
// {value: "Ending", done: true}
console.log(grenDome.next());
// {value: undefined, done: true}

粗略實現(xiàn)Generator

function makeIterator(array) {
  var nextIndex = 0;
  return {
    next: function() {
      return nextIndex < array.length ?
        {value: array[nextIndex++], done: false} :
        {value: undefined, done: true};
    }
  };
}
var it = makeIterator(["a", "b"]);
it.next() // { value: "a", done: false }
it.next() // { value: "b", done: false }
it.next() // { value: undefined, done: true }

Async/AwaitGenerator類似,Async/awaitJavascript編寫異步程序的新方法。以往的異步方法無外乎回調(diào)函數(shù)和Promise。但是Async/await建立于Promise之上,個人理解是使用了Generator函數(shù)做了語法糖。async函數(shù)就是隧道盡頭的亮光,很多人認(rèn)為它是異步操作的終極解決方案。

function a(){
    return new Promise((resolve,reject) => {
        console.log("a函數(shù)")
        resolve("a函數(shù)")
    })
}
function b (){
    return new Promise((resolve,reject) => {
        console.log("b函數(shù)")
        resolve("b函數(shù)")
    })
}
async function dome (){
    let A = await a();
    let B = await b();
    return Promise.resolve([A,B]);
}
dome().then((res) => {
    console.log(res);
});

Node.js異步I/O

當(dāng)我們發(fā)起IO請求時,調(diào)用的是各個不同平臺的操作系統(tǒng)內(nèi)部實現(xiàn)的線程池內(nèi)的線程。這里的IO請求可不僅僅是讀寫磁盤文件,在*nix中,將計算機抽象了一層,磁盤文件、硬件、套接字等幾乎所有計算機資源都被抽象為文件,常說的IO請求就是抽象后的文件。完成Node整個異步IO環(huán)節(jié)的有事件循環(huán)、觀察者、請求對象。

事件循環(huán)機制

單線程就意味著,所有任務(wù)需要排隊,前一個任務(wù)結(jié)束,才會執(zhí)行后一個任務(wù)。如果前一個任務(wù)耗時很長,后一個任務(wù)就不得不一直等著。于是就有一個概念,任務(wù)隊列。如果排隊是因為計算量大,CPU忙不過來,倒也算了,但是很多時候CPU是閑著的,因為IO設(shè)備(輸入輸出設(shè)備)很慢(比如Ajax操作從網(wǎng)絡(luò)讀取數(shù)據(jù)),不得不等著結(jié)果出來,再往下執(zhí)行。

事件循環(huán)是Node的自身執(zhí)行模型,正是事件循環(huán)使得回調(diào)函數(shù)得以在Node中大量的使用。在進程啟動時Node會創(chuàng)建一個while(true)死循環(huán),這個和Netty也是一樣的,每次執(zhí)行循環(huán)體,都會完成一次Tick。每個Tick的過程就是查看是否有事件等待被處理。如果有,就取出事件及相關(guān)的回調(diào)函數(shù),并執(zhí)行關(guān)聯(lián)的回調(diào)函數(shù)。如果不再有事件處理就退出進程。

線程只會做一件事情,就是從事件隊列里面取事件、執(zhí)行事件,再取事件、再事件。當(dāng)消息隊列為空時,就會等待直到消息隊列變成非空。而且主線程只有在將當(dāng)前的消息執(zhí)行完成后,才會去取下一個消息。這種機制就叫做事件循環(huán)機制,取一個消息并執(zhí)行的過程叫做一次循環(huán)。

while(true) {
    var message = queue.get();
    execute(message);
}

我們可以把整個事件循環(huán)想象成一個事件隊列,在進入事件隊列時開始對事件進行彈出操作,直至事件為0為止。

process.nextTick

process.nextTick()方法可以在當(dāng)前"執(zhí)行棧"的尾部-->下一次Event Loop(主線程讀取"任務(wù)隊列")之前-->觸發(fā)process指定的回調(diào)函數(shù)。也就是說,它指定的任務(wù)總是發(fā)生在所有異步任務(wù)之前,當(dāng)前主線程的末尾。(nextTick雖然也會異步執(zhí)行,但是不會給其他io事件執(zhí)行的任何機會);

process.nextTick(function A() {
  console.log(1);
  process.nextTick(function B(){console.log(2);});
});
setTimeout(function C() {
  console.log(3");
}, 0);
// 1
// 2
// 3
異步過程的構(gòu)成要素

異步函數(shù)實際上很快就調(diào)用完成了,但是后面還有工作線程執(zhí)行異步任務(wù),通知主線程,主線程調(diào)用回調(diào)函數(shù)等很多步驟。我們把整個過程叫做異步過程,異步函數(shù)的調(diào)用在整個異步過程中只是一小部分。

一個異步過程的整個過程:主線程發(fā)一起一個異步請求,相應(yīng)的工作線程接收請求并告知主線程已收到通知(異步函數(shù)返回);主線程可以繼續(xù)執(zhí)行后面的代碼,同時工作線程執(zhí)行異步任務(wù);工作線程完成工作后,通知主線程;主線程收到通知后,執(zhí)行一定的動作(調(diào)用回調(diào)函數(shù))。

它可以叫做異步過程的發(fā)起函數(shù),或者叫做異步任務(wù)注冊函數(shù)。args是這個函數(shù)需要的參數(shù),callbackFn(回調(diào)函數(shù))也是這個函數(shù)的參數(shù),但是它比較特殊所以多帶帶列出來。所以,從主線程的角度看,一個異步過程包括下面兩個要素:

發(fā)起函數(shù);

回調(diào)函數(shù)callbackFn

它們都是主線程上調(diào)用的,其中注冊函數(shù)用來發(fā)起異步過程,回調(diào)函數(shù)用來處理結(jié)果。

舉個具體的栗子:

setTimeout(function,1000);

其中setTimeout就是異步過程的發(fā)起函數(shù),function是回調(diào)函數(shù)。

注:前面說得形式A(args...,callbackFn)只是一種抽象的表示,并不代表回調(diào)函數(shù)一定要作為發(fā)起函數(shù)的參數(shù),例如:

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = xxx;
xhr.open("GET", url);
xhr.send();  
總結(jié)

JavaScript的異步編程模式不僅是一種趨勢,而且是一種必要,因此作為HTML5開發(fā)者是非常有必要掌握的。采用第三方的異步編程庫和異步同步化的方法,會讓代碼結(jié)構(gòu)相對簡潔,便于維護,推薦開發(fā)人員掌握一二,提高團隊開發(fā)效率。

如果你和我一樣喜歡前端的話,可以加Qq群:135170291,期待大家的加入。

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

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/109736.html

相關(guān)文章

  • 淺析 JS 中的 EventLoop 事件循環(huán)(新手向)

    摘要:同時,如果執(zhí)行的過程中發(fā)現(xiàn)其他函數(shù),繼續(xù)入棧然后執(zhí)行。上面我們討論的其實都是同步代碼,代碼在運行的時候只用調(diào)用棧解釋就可以了。 序 Event Loop 這個概念相信大家或多或少都了解過,但是有一次被一個小伙伴問到它具體的原理的時候,感覺自己只知道個大概印象,于是計劃著寫一篇文章,用輸出倒逼輸入,讓自己重新學(xué)習(xí)這個概念,同時也能幫助更多的人理解它~ 概念 JavaScript 是一門 ...

    chadLi 評論0 收藏0
  • Node.js:淺析高并發(fā)與分布式集群

    摘要:而在單線程環(huán)境下,繞不過錯誤就意味著導(dǎo)致應(yīng)用退出,重啟恢復(fù)的間隙會導(dǎo)致服務(wù)中斷,這是我們不愿意看到的。這也是支持高并發(fā)的重要原因之一實際上不光是操作,的絕大多數(shù)操作都是以這種異步的方式進行的。 本文首發(fā)于我的個人博客: kmknkk.xin 不足之處歡迎斧正! Node特性:高并發(fā) 在解釋node為什么能夠做到高并發(fā)之前,不妨先了解一下node的其他幾個特性: 單線程 我們先來明確...

    Lin_YT 評論0 收藏0
  • 淺析ajax

    摘要:如果響應(yīng)的內(nèi)容類型是或,這個屬性將保存包含著響應(yīng)數(shù)據(jù)的文檔。響應(yīng)的狀態(tài)狀態(tài)的說明當(dāng)對象把一個請求發(fā)送到服務(wù)器的過程中會經(jīng)歷幾個狀態(tài),直到請求被處理,然后才接收一個回應(yīng)。 1.什么是Ajax Ajax:是Asynchronous Javascript And XML的簡寫,即異步JavaScript和XML用途:動態(tài)刷新局部數(shù)據(jù),無需卸載整個頁面,從而帶來更好的用戶體驗Ajax核心:XM...

    objc94 評論0 收藏0
  • 淺析javascript調(diào)用棧

    摘要:調(diào)用棧是一種棧結(jié)構(gòu)它用來存儲計算機程序執(zhí)行時候其活躍子程序的信息。調(diào)用棧是解析器的一種機制。并形成一個棧幀任何被這個函數(shù)調(diào)用的函數(shù)會進一步添加到調(diào)用棧中,形成另一個棧幀并且運行到它們被上個程序調(diào)用的位置。然后調(diào)用棧繼續(xù)運行其他部門。 大家在進行javascript開發(fā)的時候,有沒有想過,我們寫的代碼是怎么樣運行的呢?下面我們就來剖析一下代碼的執(zhí)行過程。 一 什么是調(diào)用棧 代碼在運行過程...

    diabloneo 評論0 收藏0
  • 淺析 Vue 2.6 中的 nextTick 方法

    摘要:核心的異步延遲函數(shù),用于異步延遲調(diào)用函數(shù)優(yōu)先使用原生原本支持更廣,但在的中,觸摸事件處理程序中觸發(fā)會產(chǎn)生嚴(yán)重錯誤的,回調(diào)被推入隊列但是隊列可能不會如期執(zhí)行。 淺析 Vue 2.6 中的 nextTick 方法。 事件循環(huán) JS 的 事件循環(huán) 和 任務(wù)隊列 其實是理解 nextTick 概念的關(guān)鍵。這個網(wǎng)上其實有很多優(yōu)質(zhì)的文章做了詳細(xì)介紹,我就簡單過過了。 以下內(nèi)容適用于瀏覽器端 JS,...

    fobnn 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<