es6 promiss
在使用AJAX的时候很好奇他是如何实现链式调用的,于是自己在工作之余去学习了一下。做一个分享:
首先,回顾一下jQuery的ajax操作的传统写法:
$.ajax({
url: "test.html",
success: function(){
alert("哈哈,成功了!");
},
error:function(){
alert("出错啦!");
}
});
现在,新的写法是这样的:
$.ajax("test.html") .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); });
以上写法是基于jQuery的deferred对象,他的写法是这样子的:
var dtd = $.Deferred(); // 新建一个Deferred对象 var wait = function(dtd){ var tasks = function(){ alert("执行完毕!"); dtd.resolve(); // 改变Deferred对象的执行状态 }; setTimeout(tasks,5000); return dtd.promise(); // 返回promise对象 }; var d = wait(dtd); // 新建一个d对象,改为对这个对象进行操作 $.when(d) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); });
现在大多数高版本浏览器都实现了es6的写法,就是低版本也可以通过babel去做一个转换。在es6中已经实现了promiss的写法,可以通过自己封装一个AJAX来支持链式执行异步函数。
function ajax(method, url, data) { var request = new XMLHttpRequest(); return new Promise(function (resolve, reject) { request.onreadystatechange = function () { if (request.readyState === 4) { if (request.status === 200) { resolve(request.responseText); } else { reject(request.status); } } }; request.open(method, url); request.send(data); }); } ajax('GET', '/api/categories') .then(function (text) { // 如果AJAX成功,获得响应内容 console.log(text); }).catch(function (status) { // 如果AJAX失败,获得响应代码 console.log('err:'+status); });
jquery中有$.when()方法可以同时发起多个请求,当所有请求成功时执行done会掉函数。Promiss同样可以发起多个请求:
var p1 = new Promise(function (resolve, reject) { setTimeout(resolve, 500, 'P1'); }); var p2 = new Promise(function (resolve, reject) { setTimeout(resolve, 600, 'P2'); }); // 同时执行p1和p2,并在它们都完成后执行then: Promise.all([p1, p2]).then(function (results) { console.log(results); // 获得一个Array: ['P1', 'P2'] });
也可以发起多个请求,只要任意一个成功就会执行回调函数。
var p1 = new Promise(function (resolve, reject) { setTimeout(resolve, 500, 'P1'); }); var p2 = new Promise(function (resolve, reject) { setTimeout(resolve, 600, 'P2'); }); Promise.race([p1, p2]).then(function (result) { console.log(result); // 'P1' });