异步编程是Javascript
的特性之一,正是因为这种特性,才使得我们在浏览网页的时候,即使同时加载非常多的文件图片,也能保证速度的流畅。异步编程算是弥补了JS作为单线程语言的不足。
是什么
传统的异步编程主要是通过回调函数和事件来实现的,通常我们见到的回调陷阱就是通过这种方式实现的;而ES6提出的Promise
是 异步编程的另一种解决方案,给我们提供了以同步的方式解决异步需求的选择。
所谓Promise
,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
特性
一个Promise对象代表一个异步操作,Promise
有三种状态:Pending(进行中)
、Resolved(完成)
、Rejected(失败)
。
Promise只有两种状态的转变方式,从Pending
变为Resolved
和从Pending
变为Rejected
,状态一旦转变,将会被固定,不再变化。
Promise
一旦被初始化就不能被中途取消了,另外当处于Pending
状态时,不能更具体的区分状态。
如何用
我们先来看一个标准的Promise
实例
var promise = new Promise(function(resolve, reject){
//do something
if(/*操作成功*/){
resolve(value);
}else{
reject(error);
}
});
Promise
实例化之后,可以用then方法指定Resolved
状态和Reject
状态的回调函数。
promise.then(function(value) {
//成功
}, function(error) {
//失败
}
举个栗子
我们用Promise
实现一个异步加载图片的例子。
function asyncLoadImage(url) {
return new Promise(function(resolve, reject){
//初始化图片对象
var image = new Image();
//加载成功
image.onload = function(){
resolve(image);
};
//加载失败
image.onerror = function(){
reject("图片加载失败!");
};
image.src = url;
});
}
//实际应用
asyncLoadImage("index.jpg").then(function(value){
console.log(value.src);
}, function(error){
console.log(error);
}
我们使用then()
给Promise
对象添加成功和失败的操作。
注意如果采用以下写法是不可行的。
function asyncLoadImage(url, resolve, reject) {
return new Promise(function(resolve, reject){
//....
});
}
因为必须要通过then()
,才能将方法添加到Promise
中。
再举个栗子
我们前端开发过程中,最常用的数据交互方式就是Ajax
,Ajax
就是事件驱动的异步编程,我们现在用Promise
来实现一个Ajax
操作。
var post = function(option) {
var promise = new Promise(function(resolve, reject){
var client = new XMLHttpRequest();
client.open("POST", option.url);
client.onreadystatechange = handler;
client.responseType = "json";
client.setRequestHeader("Accept", "application/json");
client.send(option.data);
function handler() {
if (this.readyState !== 4) {
return;
}
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
};
});
return promise;
};
post({
url: 'www.lingxiao.site/es6/post',
data: json,
}).then(function(result){
console.log(result);
},function(error){
console.log("Error:"+error);
});
这样我们就实现了一个简单的Ajax
方法。
最后
没有最后
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。