成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript從初級往高級走系列————異步

andot / 2571人閱讀

摘要:之所以是單線程,取決于它的實(shí)際使用,例如不可能同添加一個(gè)和刪除這個(gè),所以它只能是單線程的。所以,這個(gè)新標(biāo)準(zhǔn)并沒有改變單線程的本質(zhì)。

原文博客地址:https://finget.github.io/2018/05/21/async/
異步

什么是單線程,和異步有什么關(guān)系

什么是event-loop

是否用過jQuery的Deferred

Promise的基本使用和原理

介紹一下async/await(和Promise的區(qū)別、聯(lián)系)

異步解決方案

什么是單線程,和異步有什么關(guān)系
單線程-只有一個(gè)線程,只做一件事。JS之所以是單線程,取決于它的實(shí)際使用,例如JS不可能同添加一個(gè)DOM和刪除這個(gè)DOM,所以它只能是單線程的。
console.log(1);
alert(1);
console.log(2);

上面這個(gè)例子中,當(dāng)執(zhí)行了alert(1),如果用戶不點(diǎn)擊確定按鈕,console.log(2)是不會執(zhí)行的。

為了利用多核CPU的計(jì)算能力,HTML5提出WebWorker標(biāo)準(zhǔn),允許JavaScript腳本創(chuàng)建多個(gè)線程,但是子線程完全受主線程控制,且不得操作DOM。所以,這個(gè)新標(biāo)準(zhǔn)并沒有改變JavaScript單線程的本質(zhì)。
js異步
console.log(100);
setTimeout(function(){
  console.log(200);
},1000)
console.log(300);
console.log(400);
console.log(400);
.... // 這里來很多很多個(gè)console.log(400); 結(jié)果就是打印完所有的400,等一秒再打印200
event-loop

文字解釋

事件輪詢,JS實(shí)現(xiàn)異步的具體解決方案

同步代碼,直接執(zhí)行

異步函數(shù)先放在異步隊(duì)列中

待同步函數(shù)執(zhí)行完畢,輪詢執(zhí)行 異步隊(duì)列 的函數(shù)

上面那個(gè)例子的執(zhí)行效果就是這樣的:

實(shí)例分析:

這個(gè)例子中有兩種情況,取決于ajax的返回時(shí)間,如果ajax時(shí)間小于100ms它就先放進(jìn)異步隊(duì)列
Jquery Deferred Jquery1.5前后的變化
var ajax = $.ajax({
  url: "data.json",
  success: function(){
    console.log("success1");
    console.log("success2");
    console.log("success3");
  },
  error: function(){
    console.log("error");
  }
})

console.log(ajax); // 返回一個(gè)xhr對象
// 鏈?zhǔn)讲僮?var ajax = $.ajax("data.json");
ajax.done(function(){
  console.log("success1");
}).fail(function(){
  console.log("error");
}).done(function(){
  console.log()
})

console.log(ajax); // 返回一個(gè)deferred對象

無法改變JS異步和單線程的本質(zhì)

只能從寫法上杜絕callback這種形式

它是一種語法糖形式,但是解耦了代碼

很好的體現(xiàn):開放封閉原則(對擴(kuò)展開放,對修改封閉)

使用Jquery Deferred
// 給出一段非常簡單的異步操作代碼,使用setTimeout函數(shù)
var wait = function(){
  var task = function(){
    console.log("執(zhí)行完成)
  }
  setTimeout(task, 2000);
}
wait();

新增需求:要在執(zhí)行完成之后進(jìn)行某些特別復(fù)雜的操作,代碼可能會很多,而且分好幾個(gè)步驟

function waitHandle(){
  var dtd = $.Deferred(); // 創(chuàng)建一個(gè)deferred對象
  
  var wait = function(dtd){ // 要求傳入一個(gè)deferred對象
    var task = function(){
      console.log("執(zhí)行完成");
      dtd.resolve(); // 表示異步任務(wù)已經(jīng)完成
      // dtd.reject(); // 表示異步任務(wù)失敗或出錯(cuò)
    }
    setTimeout(task, 2000);
    return dtd; // 要求返回deferred對象
  }
  
  // 注意,這里一定要有返回值
  return wait(dtd);
}

var w = waitHandle();
w.then(function(){
  console.log("ok 1");
}, function(){
  console.log("err 1");
}).then(function(){
  console.log("ok 2");
}, function(){
  console.log("err 2");
})

當(dāng)執(zhí)行dtd.reject()時(shí):

var w = waitHandle();
w.then(function(){
  console.log("ok 1");
}, function(){
  console.log("err 1");
})
// 不能鏈?zhǔn)?w.then(function(){
  console.log("ok 2");
}, function(){
  console.log("err 2");
})

上面封裝的waitHandle方法,由于直接返回了dtd(deferred對象),所以用戶可以直接調(diào)用w.reject()方法,導(dǎo)致無論是成功還是失敗,最后都走失敗。

// 修改
function waitHandle(){
  var dtd = $.Deferred();
  var wait = function(dtd){
    var task = function(){
      console.log("執(zhí)行完成");
      dtd.resolve(); 
    }
    setTimeout(task, 2000);
    return dtd.promise(); // 注意這里返回的是promise,而不是直接返回deferred對象
  }
  return wait(dtd);
}
ES6的Promise:點(diǎn)這里
// promise封裝一個(gè)異步加載圖片的方法
function loadImg(src) {
  var promise = new Promise(function(resolve,reject){
    var img = document.createElement("img");
    img.onload = function(){
      resolve(img)
    }
    img.onerror = function(){
      reject("圖片加載失敗")
    }
    img.src = src;
  })
  return promise;
}
async/await
這是ES7提案中的,現(xiàn)在babel已經(jīng)開始支持了,koa也是用async/await實(shí)現(xiàn)的。

then 只是將callback拆分了

async/await 是最直接的同步寫法

// 偽代碼
const load = async function(){
  const result1 = await loadImg(src1);
  console.log(result1);
  const result2 = await loadImg(src2);
  console.log(result2);
}
load();
最后

創(chuàng)建了一個(gè)前端學(xué)習(xí)交流群,感興趣的朋友,一起來嗨呀!

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

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/99515.html

相關(guān)文章

  • JavaScript初級高級系列————prototype

    摘要:原文博客地址另一篇轉(zhuǎn)載的從初級往高級走系列原型定義原型是對象的一個(gè)屬性,它定義了構(gòu)造函數(shù)制造出的對象的公共祖先。 原文博客地址:https://finget.github.io/2018/09/13/proto/另一篇轉(zhuǎn)載的JavaScript從初級往高級走系列————prototype 原型 定義: 原型是function對象的一個(gè)屬性,它定義了構(gòu)造函數(shù)制造出的對象的公共祖先。通...

    SKYZACK 評論0 收藏0
  • JavaScript初級高級系列————MVVM-Vue

    摘要:原文博客地址如何理解如何實(shí)現(xiàn)是否解讀過的源碼與框架的區(qū)別實(shí)現(xiàn)實(shí)現(xiàn)獨(dú)立初始化實(shí)例兩者的區(qū)別數(shù)據(jù)和視圖的分離,解耦開放封閉原則,對擴(kuò)展開放,對修改封閉在中在代碼中操作視圖和數(shù)據(jù),混在一塊了以數(shù)據(jù)驅(qū)動視圖,只關(guān)心數(shù)據(jù)變化, 原文博客地址:https://finget.github.io/2018/05/31/mvvm-vue/ MVVM 如何理解 MVVM 如何實(shí)現(xiàn) MVVM 是否解讀過 ...

    codercao 評論0 收藏0
  • JavaScript初級高級系列————Virtual Dom

    摘要:當(dāng)中的一些元素需要更新屬性,而這些屬性只是影響元素的外觀,風(fēng)格,而不會影響布局的,比如。則就叫稱為重繪。 原文博客地址:https://finget.github.io/2018/05/22/virtualDom/ 什么是虛擬DOM 用JS模擬DOM結(jié)構(gòu) DOM變化的對比,放在JS層來做(圖靈完備語言) 提高重繪性能 重繪和回流 頁面渲染過程:showImg(https://seg...

    tinyq 評論0 收藏0
  • JavaScript初級高級系列————ES6

    摘要:采用二八定律,主要涉及常用且重要的部分。對象是當(dāng)前模塊的導(dǎo)出對象,用于導(dǎo)出模塊公有方法和屬性。箭頭函數(shù)函數(shù)箭頭函數(shù)把去掉,在與之間加上當(dāng)我們使用箭頭函數(shù)時(shí),函數(shù)體內(nèi)的對象,就是定義時(shí)所在的對象,而不是使用時(shí)所在的對象。 ES6 原文博客地址:https://finget.github.io/2018/05/10/javascript-es6/ 現(xiàn)在基本上開發(fā)中都在使用ES6,瀏覽器環(huán)境...

    孫淑建 評論0 收藏0
  • javascript知識點(diǎn)

    摘要:模塊化是隨著前端技術(shù)的發(fā)展,前端代碼爆炸式增長后,工程化所采取的必然措施。目前模塊化的思想分為和。特別指出,事件不等同于異步,回調(diào)也不等同于異步。將會討論安全的類型檢測惰性載入函數(shù)凍結(jié)對象定時(shí)器等話題。 Vue.js 前后端同構(gòu)方案之準(zhǔn)備篇——代碼優(yōu)化 目前 Vue.js 的火爆不亞于當(dāng)初的 React,本人對寫代碼有潔癖,代碼也是藝術(shù)。此篇是準(zhǔn)備篇,工欲善其事,必先利其器。我們先在代...

    Karrdy 評論0 收藏0

發(fā)表評論

0條評論

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