promise对象
1.promise的含义
promise是异步编程一种解决方案,比传统的解决方案--回调函数和事件更合理、更强大。所谓promise简单说就是一个容器,里面保存某个未来才会结束的事件结果。
从语法上说,promise是一个对象,可以从他获取异步操作的消息。promise提供统一的API,各种异步操作都可以使用同样的方法进行处理。
2.promise对象有两个特点
1)对象的状态不受外界影响。有3种状态:pending(进行中)、fulfilled(已成功)、rejeced(已失败)。只有异步操作的结果可以决定当前是哪种状态,任何其他操作无法改变这种状态。
2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。promise对象的状态改变,只能两种可能:从pending变为fulfilled,从pending变为resjected.主要这两种情况发生状态就凝固不会再变了,并一直保持这种结果,这时就成为resoved(已定型)/如果改变已经发生了,再对promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果错过了再去监听,将不会得到结果。
有了promise对象,就可以将异步操作以同步操作的流程表达出来,避免使用层层嵌套的回调函数。此外对象提供统一的接口,使得异步操作更加容易。
3.promise对象缺点
1)无法取消,一旦新建立即执行,无法中途取消
2)如果不设置回调函数,内部抛出错误不会反映到外部
3)处于pending状态无法判断处于哪个阶段,是刚开始还是已经完成。
基本用法
ES6规定,Promise对象是一个构造函数,用来生产promise实例。
promise构造函数接收一个函数作为参数,该函数的两个参数分别是resolve和reject。他们是两个函数,由javascript引擎提供,不用自己部署。
resolve函数的作用是将promise对象的状态从‘未完成’变为‘成功’,在异步操作成功时调用,并将异步操作的结果作为参数传递出去。。
reject函数的作用是将promise对象的状态从‘未完成’变为‘失败’,在异步操作失败时调用,并将报错作为参数传递出去
在promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。
then方法可以接受两个回调函数作为参数。
第一个是promise对象的状态变为resolved时调用,第二个是状态变为rejected时调用,第二个回调函数是可选的,不一定提供。他们都接受promise对象传出的值作为参数。
const promise = new Promise(function(resolved,rejected){ // ... some code if(/*异步操作成功*/){ resolve(value); } else { reject(error); } }); promise.then( function(value){ // success }, function(error){ //failure } );
手写一个promise
const PENDING = "pending"; const RESOLVED = "resolved"; const REJECTED = "rejected"; function MyPromise(fn) { // 保存初始化状态 var self = this; // 初始化状态 this.state = PENDING; // 用于保存 resolve 或者 rejected 传入的值 this.value = null; // 用于保存 resolve 的回调函数 this.resolvedCallbacks = []; // 用于保存 reject 的回调函数 this.rejectedCallbacks = []; // 状态转变为 resolved 方法 function resolve(value) { // 判断传入元素是否为 Promise 值,如果是,则状态改变必须等待前一个状态改变后再进行改变 if (value instanceof MyPromise) { return value.then(resolve, reject); } // 保证代码的执行顺序为本轮事件循环的末尾 setTimeout(() => { // 只有状态为 pending 时才能转变, if (self.state === PENDING) { // 修改状态 self.state = RESOLVED; // 设置传入的值 self.value = value; // 执行回调函数 self.resolvedCallbacks.forEach(callback => { callback(value); }); } }, 0); } // 状态转变为 rejected 方法 function reject(value) { // 保证代码的执行顺序为本轮事件循环的末尾 setTimeout(() => { // 只有状态为 pending 时才能转变 if (self.state === PENDING) { // 修改状态 self.state = REJECTED; // 设置传入的值 self.value = value; // 执行回调函数 self.rejectedCallbacks.forEach(callback => { callback(value); }); } }, 0); } // 将两个方法传入函数执行 try { fn(resolve, reject); } catch (e) { // 遇到错误时,捕获错误,执行 reject 函数 reject(e); } } MyPromise.prototype.then = function(onResolved, onRejected) { // 首先判断两个参数是否为函数类型,因为这两个参数是可选参数 onResolved = typeof onResolved === "function" ? onResolved : function(value) { return value; }; onRejected = typeof onRejected === "function" ? onRejected : function(error) { throw error; }; // 如果是等待状态,则将函数加入对应列表中 if (this.state === PENDING) { this.resolvedCallbacks.push(onResolved); this.rejectedCallbacks.push(onRejected); } // 如果状态已经凝固,则直接执行对应状态的函数 if (this.state === RESOLVED) { onResolved(this.value); } if (this.state === REJECTED) { onRejected(this.value); } };