JS异步那些事 一 (基础知识)
JS异步那些事 二 (分布式事件)
JS异步那些事 三 (Promise)
JS异步那些事 四(HTML 5 Web Workers)
JS异步那些事 五 (异步脚本加载)
Promise,Deferred 对象
前戏
先来谈谈jquery中的promise的使用,来看一个例子
原本写一个小动画我们可能是这样的
<script type="text/javascript">
$('.animateEle').animate({
opacity:'.5'
}, 4000,function(){
$('.animateEle2').animate({
width:'100px'
},2000,function(){
$('.animateEle3').animate({
height:'0'
},2000);
});
});
</script>
但是如果我们使用promis对象的话,就可以使得代码更加简单易懂
<script type="text/javascript">
var animate1 = function() {
return $('.animateEle1').animate({opacity:'.5'},4000).promise();
};
var animate2 = function() {
return $('.animateEle2').animate({width:'100px'},2000).promise();
};
var animate3 = function(){
return $('.animateEle3').animate({height:'0'},2000).promise();
};
$.when(animate1()).then(animate2).then(animate3);
</script>
看了上面的例子大概对promise的作用有一定的了解了吧,那就来说说promis的原理吧
Promise对象方法
对于DOM,动画,ajax相关方法,都可以使用 promise 方法。调用 promise 方法,返回的是 promise 对象。可以链式调用 promise 方法。
比如jquery中的ajax的 $.post $.get $.ajax 等方法,实际上都是默认调用了promise方法,然后返回了一个promise对象
promise对象常见的方法有三个 : done , fail , then 。
<script type="text/javascript">
$.get('/',{}).done(function(data){
console.log('success');
}).fail(function(){
console.log('fail');
});
</script>
jquery 这里的接口方法太多了,就跟早期的事件方法绑定一样, live , delegate , bind ,最终还是归为 on
deferred对象方法
deferred 对象呢,也就是使用 $.Deferred() 方法,以及 $.when() 等方法创造出来的对象,它可以理解为一个升级版特殊的的promise对象
来看看一个例子
<script type="text/javascript">
var promisepbj = new $.Deferred();
promisepbj.done(function() {
console.log('haha,done');
}).fail(function() {
console.log('失败了');
}).always(function(res) {
console.log('我总是被执行啦');
});
//使用resolve或者reject就可以调用defferred对象了
promisepobj.resolve();
//promisepobj.reject();
resolve 方法会触发 done 的回调执行, reject 会触发 fail 的回调,对于 always 方法,deferred 对象,无论是 resolve 还是 reject ,都会触发该方法的回调。
ES6 Promise
前面讲了很多jquery的promise实现,$.Deferred 和 ES2015 的 Promise 是不同的东西,因为前者不符合 Promises/A+ 规范。 Promise 对象在 EMCAScript 2015 当中已经成为标准。现在要来谈谈马上要成为主流趋势的es6原生promise对象,首先贴一个很详细的es6 promise的小书,基本你知道的不知道都在里面 http://liubin.org/promises-book/#introduction,
把promise解释的很清楚的文章很多,我自认为我写不到他们那么好,索性干脆把阮一峰大神的文章贴出来 http://es6.ruanyifeng.com/#docs/promise
我就来个简化版本的吧,用最短的字数来入个门。
定义:
谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
特点:
有三种状态:Pending(进行中)、Resolved(已完成,又称Fulfilled)和Rejected(已失败)。
一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从Pending变为Resolved和从Pending变为Rejected。只要这两种情况发生,状态就凝固了
基本用法
<script type="text/javascript">
var promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
</script>
Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。
<script type="text/javascript">
function timeout(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms, 'done');
});
}
timeout(100).then((value) => {
console.log(value);
});
</script>
上面代码中,timeout方法返回一个Promise实例,表示一段时间以后才会发生的结果。过了指定的时间(ms参数)以后,Promise实例的状态变为Resolved,就会触发then方法绑定的回调函数。
异常处理
异常处理一直是回调的难题,而promise提供了非常方便的catch方法:在一次promise调用中,任何的环节发生reject,都可以在最终的catch中捕获到:
Promise.resolve().then(function(){
return loadImage(img1);
}).then(function(){
return loadImage(img2);
}).then(function(){
return loadImage(img3);
}).catch(function(err){
//错误处理
})
基本的 api
Promise.resolve()
Promise.reject()
Promise.prototype.then()
Promise.prototype.catch()
Promise.all()
Promise.race()
小结
具体的很多的用法可以参考阮一峰的 http://es6.ruanyifeng.com/#docs/promise 入门教程,还有就是上面提到的电子书 http://liubin.org/promises-book/#introduction。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。