es6中新增了promise对象,为了处理异步消息而生,在此之前处理异步拿到的数据就是回调嵌套回调,有了Promise我们就可以在需要使用异步处理结果的地方调用Promise.then(func)
摘自 阮一峰 ECMAScript 6 入门
所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
在js中很经典的异步就是ajax请求了,我在第一个项目当中用到ajax原生请求,处理ajax请求的结果全在回调函数当中进行,判断状态码,作出相应的处理,在不同的状态码下的处理又非常的多,然后就是一层层嵌套,还蛮爽的==
function getMessage(url,data) {
var request = new XMLHttpRequest();
request.open("POST", url);
request.responseType = "json";
request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
request.send(data);
request.onload = function () {
if (this.status === 200) {
if (this.response.code === 200) {
this.response.data.forEach(function (obj) {
//此处处理拿到的数据
})
} else
//此处处理后端返回错误
} else
//此处处理网络请求错误
};
}
基本上整个模块的操作都在回调里面做了,因为请求的结果数据就在那里,异步的结果是不确定的,只能在回调函数做各种各样的处理。
一个 Promise有以下几种状态:
描述:
Promise 对象是一个代理对象(代理一个值),被代理的值在Promise对象创建时可能是未知的。它允许你为异步操作的成功和失败分别绑定相应的处理方法(handlers )。 这让异步方法可以像同步方法那样返回值,但并不是立即返回最终执行结果,而是一个能代表未来出现的结果的promise对象。
我们给出一个用promise对象封装的一个ajax请求:
function getDate(url, data) {
return new Promise(function(resolve, reject) {
var request = new XMLHttpRequest();
request.open("POST", url);
request.responseType = "json";
request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
request.send(data);
request.onload = function() {
if (this.status === 200) {
resolve(this.response);
} else {
reject(this.status);
}
}
})
}
// 在需要处理数据的地方
getDate(url, data).then(function(response) {
/此处处理拿到的数据
}).catch(function(err){
//此处处理错误
})
上面的示例就是用Promise对象封装了ajax请求,解决了在回调里面处理所有结果的尴尬。
我们可以不用人工封装,而是借助已经封装好的模块axios去请求,原理看着都一样,甚至用起来和我们自己封装的都一样
function getDate(url, data) {
axios.defaults.baseURL = url;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
//此处放了一个get请求,就没用到data
axios.get('/articles/articleList').then(function(response) {
if(response.status == 200) {
if(response.data.code == 200) {
//处理
} else {
//此处处理后端返回状态错误
}
}
}).catch(function(err) {
//此处处理请求错误
});
}
这里我要隆重的说一句,不管这个Promise对异步的结果做了什么,异步还是异步,你想把异步执行的结果传出来还是不可能,除非用generator或者async转成同步,显然把他转成同步不合算。
接下来我们就用箭头函数加promise的方法解决结果不能传出去的问题。
ES6大法的箭头函数,说一点:箭头函数的this。
箭头函数的this是绑定外部环境的,咱们直接看例子
var name = "zhangchi";
var Obj = {
name: "chichi",
fun1: function(){
console.log(this.name);
},
fun2: () => {
console.log(this.name);
}
}
Obj.fun1(); // chichi
Obj.fun2(); //zhangchi
看完这个例子大致就知道,箭头函数和普通函数的this指向是不同的,所以不要在一个类里面用箭头函数。
var data = {}; //接收异步返回的结果
function getDate(url, data) {
axios.defaults.baseURL = url;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
axios.get('/articles/articleList').then((response) => {
if(response.status == 200) {
if(response.data.code == 200) {
this.data = response.data.data;
} else {
//此处处理后端返回状态错误
}
}
}).catch(function(err) {
//此处处理请求错误
});
}