异步编程是Javascript
的特性之一,正是由于这种特性,才使得咱们在浏览网页的时候,即便同时加载很是多的文件图片,也能保证速度的流畅。异步编程算是弥补了JS做为单线程语言的不足。前端
传统的异步编程主要是经过回调函数和事件来实现的,一般咱们见到的回调陷阱就是经过这种方式实现的;而ES6提出的Promise
是 异步编程的另外一种解决方案,给咱们提供了以同步的方式解决异步需求的选择。es6
所谓Promise
,简单说就是一个容器,里面保存着某个将来才会结束的事件(一般是一个异步操做)的结果。编程
一个Promise对象表明一个异步操做,Promise
有三种状态:Pending(进行中)
、Resolved(完成)
、Rejected(失败)
。json
Promise只有两种状态的转变方式,从Pending
变为Resolved
和从Pending
变为Rejected
,状态一旦转变,将会被固定,再也不变化。promise
Promise
一旦被初始化就不能被中途取消了,另外当处于Pending
状态时,不能更具体的区分状态。app
咱们先来看一个标准的Promise
实例异步
var promise = new Promise(function(resolve, reject){ //do something if(/*操做成功*/){ resolve(value); }else{ reject(error); } });
Promise
实例化以后,能够用then方法指定Resolved
状态和Reject
状态的回调函数。async
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
方法。
没有最后