说一说promise

一、ES6 promise

现在ES6很火,今天打算捋一捋ES6中promise,弄清楚核心,掌握这个知识点。

promise到底是什么?

通过console.dir(Promise)
在这里插入图片描述

我们可以看到Promise是一个构造函数,有 resolve,reject,all,race 等方法,也有catch,then 等构造方法

resolve,reject

解析一个Promise例子:

例子1:
var p = new Promise(function(resolve,reject){
	//这里一般有异步操作
	console.log("执行到此")
	resolve("执行成功")
	reject("执行失败")	
})

其实 resolve 和 reject 大致相当于一个优化过的回调函数,如果函数执行失败(状态为reject),就会执行 reject 方法,如果函数顺利执行(状态为 fullfiled),就会执行其实 resolve 方法。

这里有一点,如果函数里面有其他操作,无论成功与否,都会先执行,所以会先输出“执行到此”。

为此,一般都是把promise包在函数中,阻止其他操作自动执行。通过在函数中返回这个promise实例,执行函数

例子2:
function runPromise(){
	var p = new Promise(function(resolve,reject){
		//这里一般是异步操作
		console.log("执行到此")
		resolve("执行成功")
		reject("执行失败")	
    });	
	return p;
}

runPromise();

then

有了例子2,接下去就是ES6的一个精髓,链式操作(对付回调地狱的一种方式)

例子3:
runPromise().then( function(){return x;} )
	.then( function(){return y;} )
	.then( function(){return z;} )

第一个 then 方法相当于 resolve,在 runPromise 正常执行时调用,第二个 then 方法处理第一个 then 返回的值,如此类推。

如果想处理 runPromise 失败的调用,

例子4
runPromise().then( function(data1){return x;},function(data2){return x;} )
	.then( function(){return y;} )
	.then( function(){return z;} )

catch

当然例子4中可以用 catch 替 then 的失败调用

例子5:
runPromise().then( function(){return x;} )
	.catch( function(){return y;} )

当然,这里的 catch 还有更多的功能,就是在上述代码出异常(代码错误时),不会卡死报错,会进入 catch 方法,与 try/catch 方法有相同功能。

all

如果你想同时输出多个 Promise 怎么办,用 all 方法,可实现并行执行异步操作的能力,并且是在Promise里的所有异步操作执行完才回调

例子6
Promise.all([方法1,方法2,方法3]).then(function(){});

这里会先执行方法1,方法2,方法3的普通方法,然后把他们的resolve()输出成一个数组。

输出如下:

方法1普通输出
方法2普通输出
方法3普通输出
[方法1的resolve(),方法2的resolve(),方法3的resolve()]

这种操作可用于预加载各种资源如图片等

race

all 方法的效果实际上是「谁跑的慢,以谁为准执行回调」,那么相对的就有另一个方法「谁跑的快,以谁为准执行回调」,这就是race方法,这个词本来就是赛跑的意思。

例子7
Promise.race([方法1,方法2,方法3]).then(function(){});

假设方法1最先输出,则:

方法1普通输出
方法2普通输出
方法3普通输出
方法1的resolve()

二、JQuery的deferred

jquery 用 $.Deferred 实现了Promise规范(这是一种理念)

$.Deferred() 创造了一个Deferred对象,一个 Deferred 对象开始于挂起状态,任何使用 deferred.then, deferred.always, deferred.done, 或者 deferred.fail 添加到这个对象的回调函数都是排队等待执行的。调用 deferred.resolve 转换延迟状态到解决状态后立即执行设置的 doneCallbacks 。调用 deferred.reject 转换延迟状态到拒绝状态后立即执行设置的 failCallbacks 。一旦对象已经进入了解决或拒绝状态,它将一直保持该状态。

done、fail、always

jquery增加了两个语法糖方法,done 和 fail,分别用来指定执行完成和执行失败的回调

var deferred = $.Deferred();
var promise = deferred.promise();
/* $.Deferred 的特性在外部可以操作deferred的状态,
所以加上 promise 方法拒接外部操作状态*/

这里:
promise.then(function(){
    console.log('执行完成');
}, function(){
    console.log('执行失败');
});

相当于:
promise.done(function(){
    console.log('执行完成');
})
.fail(function(){
    console.log('执行失败');
})
//.always(function(){
//    console.log('一定执行');
//});

done 相当于添加 deferred.reslove 的回调,fail 相当于添加 deferred.reject 的回调。但不管成功与否,都会执行 always() 添加的回调。always也是一个语法糖。

then

和ES6的Promise对象一样,也支持then方法

when

与ES6中的all方法功能一样,并行执行异步操作,在所有的异步操作执行完后才执行回调函数。不过与ES6的all的参数稍有区别,它接受的并不是数组,而是多个Deferred对象。

$.when(方法1(), 方法2(), 方法3())
.then(function(data1, data2, data3){
    console.log('全部执行完成');
    console.log(data1, data2, data3);
});

这里,jquery 中没有像 ES6 中的 race 方法

再拓展 Deferred 对象的使用方法

把普通操作封装成一个回调函数

var $def = $.Deferred();
var wait = function(){
	var tasks = function(){
		alert("执行完毕!");
		$def.resolve(); // 改变deferred对象的执行状态
	}

	tasks();

	return $def.promise();
}

$.when(wait())
	.done(function(){ alert("执行成功!"); })
	.fail(function(){ alert("执行出错!"); });

三、ajax与Deferred的关系

success、error与complete

分别表示ajax请求成功、失败、结束的回调。是Ajax的语法糖。

success对应done,error对应fail,complete对应always,就这样,只是为了与ajax的参数名字上保持一致而已

例子:
$.ajax(/*...*/)
	.success(function(){/*...*/})
	.error(function(){/*...*/})
	.complete(function(){/*...*/})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值