什么是 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); } );