原文博客地址: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