本文从js的异步处理出发,引入Promise的概念,而且介绍Promise对象以及其API方法。segmentfault
能够参考这篇文章
js是单线程的,
在js里,异步处理总共有四种方法,其中最多见的一种方法是采用回调函数的方式数组
function f1(callback){ setTimeout(function(){ callback(); },1000) } f1(f2);
另外除了回调函数,事件监听的机制也会进行异步处理。任务的执行不取决于代码的顺序,而是取决于事件是否会发生。promise
若是是业务逻辑不复杂还好说,但是若是业务逻辑很复杂的话,回调嵌套的不少,代码书写起来会变得很复杂很难看懂。
还有一个问题是,若是有多个异步操做,那么就存在一个处理顺序的问题,代码如何按照但愿的顺序执行。异步
Promise是抽象异步处理对象以及对其进行各类操做的组件。Promise并非从js里出现的概念。
Promise则是把相似的异步处理对象和处理规则进行规范化, 并按照采用统一的接口来编写,而采起规定方法以外的写法都会出错。函数
首先说,Promise是一个对象,因此说这个对象与js里的其余对象没什么不同的。要说不同凡响的地方时,Promise对象充当代理的做用,充当异步操做和回调函数之间的中介学习
Promise的思想是:每次执行一个异步操做之后,马上返回一个Promise对象,由于是马上操做,因此咱们能够进行同步操做流程。这个Promise对象有一个then方法,指定回调函数,用于在异步操做执行完后执行回调函数处理。线程
//换成Promise的写法 new Promise(f5).then(f4).then(f3).then(f2).then(f1)
使用Promise,用同步的写法处理异步操做的代码,使得代码清晰易懂,等一个异步函数处理完成以后,才会执行下一个then里边的函数。这样就避免了前边的多个回调可能引起的顺序问题。代理
前边说过,Promise接口的做用是,返回一个Promise对象。
一个Promise对象有三种状态code
pending 异步操做未完成对象
resolve 异步操做已成功完成
reject 异步操做失败
至于这三种关系的途径能够描述为两种
pending ---> resolve
pending ---> reject
这种变化只会出现一次。因此,意思是,一个异步操做结束以后只会有两种状态,成功or失败。异步操做成功时,Promise对象返回一个值,对象状态变为resolve,异步操做失败时,对象状态变为reject。
Promise对象用then方法添加回调函数,then方法支持链式调用。
promise.then(onFulfilled, onRejected)
then方法接受两个参数,看名字就知道第一个参数是Promise对象状态时resolve的时候调用,而第二个参数能够省略,表示Promise调用失败状态是reject的时候执行这个回调。
除了then方法,还有一个专门处理异常的方法.
.catch 也能够理解为 promise.then(undefined, onRejected) 。
promise.catch(onRejected)
then和catch两个方法是写到了Promise对象的原型上的,每一个Promise对象均可以调用。
ES6提供了原生的Promise对象构造函数,用于生成Promise对象,
var promise = new Promise(function(resolve, reject){ // 异步操做的代码 if (/* 异步操做成功 */){ resolve(value); } else { reject(error); } });
Promise对象接收一个函数做为构造函数的参数,这个函数一样有两个参数,这两个参数是由js引擎提供的函数,不用本身来部署。
resolve函数的做用是把Promise对象的状态从pending变为resolve,在异步操做成功的时候调用,而且将异步操做的结果做为参数传过去。一样的,reject函数的做用是把对象状态从pending变成reject,在失败的时候调用,而且传递结果参数。
接下来,当Promise对象建立成功以后就能够用then方法链式调用了。
通常状况下,咱们会用构造函数的方法建立Promise对象。可是,除此以外咱们也会有其余方法建立。
静态方法Promise.resolve(value)被认为是new Promise方式建立Promise对象的快捷方式。
Promise.resolve(42).then(function(value){ console.log(value); })
resolve()会让对象状态当即变成resolved,而且将形参马上传给下一个回调。
这个方法相似上一个方法,也是建立Promise对象的快捷方式,可是只会把Promise对象从pending变为rejected。参数是一个异常对象,传递给下一个catch方法或者then方法。
Promise.reject(new Error("BOOM!")).catch(function(error){ console.error(error); });
到目前为止,已经学习了建立Promise对象和用then,catch方法来注册回调函数。若是只有一个Promise对象的话很好说,可是若是有多个Promise对象的时候要如何处理呢。
Promise.all 接收一个 promise对象的数组做为参数,当这个数组里的全部promise对象所有变为resolve或reject状态的时候,它才会去调用 .then 方法。
Promise.race 只要有一个promise对象进入 FulFilled 或者 Rejected 状态的话,就会继续进行后面的处理。
function f1(v){ console.log(v); return 2; } function f2(v){ console.log(v) } Promise.resolve(1).then(f1).then(f2);