什么是 Promise ?
在 JavaScript 中,Promise 是一种用于处理异步操作的对象,它可以更加优雅地处理回调函数嵌套和错误处理。
promise es6已经内部实现了, ie 不兼容 promise,需要 polyfill (比如:es-promise)
Promise A+
Promise A+
规范是为了解决 Promise 的实现中出现的一些问题和不一致性,以促进 Promise 的标准化和互操作性。
Promise A+
规范定义了 Promise 对象的行为和状态转换规则,以及 then 方法的参数和返回值要求等,使不同的 Promise 实现可以遵循同样的规范,从而实现互操作性和可组合性。
promise A+
规范:https://promisesaplus.com/
Promises/A+
规范,有现成的单元测试套件,很容易搭建开发环境,以及验证代码是否符合规范要求。具体地址:https://github.com/promises-aplus/promises-tests
为什么会产生 promise,它解决了什么问题?
- 过个异步请求并发(希望同步最终结果)Promise.all
- 链式异步请求问题(上一个的输出是下一个的输入)Promise的链式调用可以解决这个问题
- 缺陷:还是基于回调
实现一个简易版本的 promise
promise 特性
- promise 有三个状态:成功态(resolve) 失败态(reject) 等待态(pending)(又不成功又不失败)
- 用户自己决定失败的原因和成功的原因,成功和失败也是用户定义的
- promise 默认执行器立即执行
- promise 的实例都拥有一个 then 方法,一个参数是成功的回调,另一个是失败的回调
- 如果执行函数时发生了异常也会执行失败的逻辑
- 如果 promise 一旦成功就不能失败,反之亦然,只有等待态的时候才能去更新状态
新建文件 kaimo-promise.js
添加下面代码
const RESOLVE = "RESOLVE"; // 成功态
const REJECT = "REJECT"; // 失败态
const PENDING = "PENDING"; // 等待态
class KaimoPromise {
constructor(executor) {
this.status = PENDING;
// value 是任意合法的 Javascript 值,(包括 undefined,thenable, promise)。
this.value = undefined;
// reason 是表示 promise 为什么被 rejected 的值
this.reason = undefined;
let resolve = (value) => {
if (this.status === PENDING) {
this.value = value;
this.status = RESOLVE;
}
};
let reject = (reason) => {
if (this.status === PENDING) {
this.reason = reason;
this.status = REJECT;
}
};
try {
// 立即执行
executor(resolve, reject);
} catch (error) {
// 处理错误异常
reject(error);
}
}
// promise 必须提供 then 方法来存取它当前或最终的值或者原因。
// then 接收两个参数:onFulfilled 和 onRejected
then(onFulfilled, onRejected) {
if (this.status === RESOLVE) {
onFulfilled(this.value);
}
if (this.status === REJECT) {
onRejected(this.reason);
}
}
}
module.exports = KaimoPromise;
使用
let KaimoPromise = require("./6/kaimo-promise.js");
let promise = new KaimoPromise((resolve, reject) => {
console.log(1);
// throw new Error("异常");
resolve("成功");
// reject("失败");
});
console.log(2);
promise.then(
(data) => {
console.log("success", data);
},
(err) => {
console.log("failed", err);
}
);