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);
}
};
原文:https://www.cnblogs.com/wzw-gjh/p/13084739.html