原文博客地址:https://finget.github.io/2018/05/21/async/
單線程-只有一個線程,只作一件事。JS之因此是單線程,取決於它的實際使用,例如JS不可能同添加一個DOM和刪除這個DOM,因此它只能是單線程的。
console.log(1); alert(1); console.log(2);
上面這個例子中,當執行了alert(1)
,若是用戶不點擊肯定按鈕,console.log(2)
是不會執行的。javascript
爲了利用多核CPU的計算能力,HTML5提出
WebWorker
標準,容許JavaScript腳本建立多個線程,可是子線程徹底受主線程控制,且不得操做DOM。因此,這個新標準並無改變JavaScript單線程的本質。
console.log(100); setTimeout(function(){ console.log(200); },1000) console.log(300); console.log(400); console.log(400); .... // 這裏來不少不少個console.log(400); 結果就是打印完全部的400,等一秒再打印200
上面那個例子的執行效果就是這樣的:
實例分析:
前端
這個例子中有兩種狀況,取決於ajax的返回時間,若是ajax時間小於100ms它就先放進異步隊列
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); // 返回一個xhr對象
// 鏈式操做 var ajax = $.ajax('data.json'); ajax.done(function(){ console.log('success1'); }).fail(function(){ console.log('error'); }).done(function(){ console.log() }) console.log(ajax); // 返回一個deferred對象
// 給出一段很是簡單的異步操做代碼,使用setTimeout函數 var wait = function(){ var task = function(){ console.log('執行完成) } setTimeout(task, 2000); } wait();
新增需求:要在執行完成以後進行某些特別複雜的操做,代碼可能會不少,並且分好幾個步驟java
function waitHandle(){ var dtd = $.Deferred(); // 建立一個deferred對象 var wait = function(dtd){ // 要求傳入一個deferred對象 var task = function(){ console.log('執行完成'); dtd.resolve(); // 表示異步任務已經完成 // dtd.reject(); // 表示異步任務失敗或出錯 } 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'); })
當執行dtd.reject()時:git
var w = waitHandle(); w.then(function(){ console.log('ok 1'); }, function(){ console.log('err 1'); }) // 不能鏈式 w.then(function(){ console.log('ok 2'); }, function(){ console.log('err 2'); })
上面封裝的waitHandle
方法,因爲直接返回了dtd
(deferred對象),因此用戶能夠直接調用w.reject()
方法,致使不管是成功仍是失敗,最後都走失敗。github
// 修改 function waitHandle(){ var dtd = $.Deferred(); var wait = function(dtd){ var task = function(){ console.log('執行完成'); dtd.resolve(); } setTimeout(task, 2000); return dtd.promise(); // 注意這裏返回的是promise,而不是直接返回deferred對象 } return wait(dtd); }
ES6的Promise: 點這裏
// promise封裝一個異步加載圖片的方法 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; }
這是ES7提案中的,如今babel已經開始支持了,koa也是用async/await實現的。
// 僞代碼 const load = async function(){ const result1 = await loadImg(src1); console.log(result1); const result2 = await loadImg(src2); console.log(result2); } load();
建立了一個前端學習交流羣,感興趣的朋友,一塊兒來嗨呀!
ajax