首页IT科技promise.then原理(Promise 实现原理)

promise.then原理(Promise 实现原理)

时间2025-06-12 18:09:34分类IT科技浏览4409
导读:一、Promise 介绍...

一             、Promise 介绍

定义

Promise 是异步编程的一种解决方法             ,比传统的回调函数和事件更合理;它是由社区提出和实现经由 ES6 将其写进语言标准                   ,并在原生提供了 Promise 对象; Promise 可以理解是一个容器      ,里面保存着某个将来才会结束的事件(异步操作)的结果;从语法上说         ,Promise 是一个对象通过它可以获取异步操作的消息;Promise 提供了统一的 API                   ,各种异步操作都可以用同样的方法进行处理             。

特点

Promise 对象代表一个异步操作         ,对象的状态不受外界影响      ,有三种状态                   ,pending(进行中)                   、fulfilled(已成功)      、rejected(已失败);只有异步操作的结果            ,可以决定当前是哪一种状态   ,任何其他操作都无法改变这个状态; 一旦状态改变就不会再变                   ,Promise 对象的状态改变               ,只有两种可能:从 pending 变为 fulfilled,从 pending 变为 rejected;如果改变已经发生了                ,你再对 Promise 对象添加回调函数                  ,也会立即得到这个结果;这与事件(event)完全不同   ,事件的特点是:如果你错过了它             ,再去监听是得不到结果的; 构造函数 Promise 必须接收一个函数(handle)作为参数                   ,函数又包含 resolve 和 reject ; then          、catch 支持链式调用;

缺点

Promise 无法取消:一旦新建就会执行      ,无法中途取消; 如果不设置回调函数         ,Promise 内部抛出的错误不会反应到外部; 当处于 pendding 状态时                   ,无法知道目前进展到哪一个阶段;

场景

有效的解决 js 异步回调地狱问题; 将业务逻辑与数据处理分隔开使代码更优雅         ,方便阅读      ,更有利于代码维护;

基本用法

let p = new Promise(function(resolve,reject){ setTimeout(function(){ resolve(成功!); },10) }).then(res=>{ console.log(成功!) })

二                   、promise 源码实现

// 定义三种状态 const REJECTED = REJECTED; const FULFILLED = FULFILLED; const PENDING = PENDING; //判断一个变量是否是 Promise 的函数:1. 是否是对象并且不是 null 2. 是否有 then 属性并且 then 是一个方法 function isPromise(val) { if (typeof val === object && val !== null || typeof val === function) { return typeof val.then === function; } return false; } //处理 x 的值                   ,如果是普通值直接返回            ,如果是 promise 则返回 x.then 执行的结果 const resolvePromise = (promise2, x) => { const { resolve, reject } = promise2; // 如果 new 出来的 Promise2 和 x 是同一个   ,直接报错 if (promise2 === x) return reject(new TypeError(Chaining cycle detected for promise #<Promise>)); // 先判断是不是对象或者函数 if (typeof x === object && x !== null || typeof x === function) { // 调用了成功就不能失败                   ,调用的失败就不能成功                   。不能多次调用成功或者失败 let called; try { // 内部可能抛出错误 const then = x.then; // 如果 x.then 不是函数就说明是一个普通值               ,直接返回 x if (typeof then !== function) { resolve(x); } else { // 利用.call将this指向 x, 防止x.then()报错 then.call(x, (res) => { if (called) return; called = true; // res 可能是一个 promise ,递归调用resolvePromise                ,直到解析出的值是普通值 resolvePromise(promise2, res); }, (err) => { if (called) return; called = true; // 直接调用 promise的 reject 作为失败的结果                  ,并向下传递 reject(err); }); } } catch(err) { if (called) return; called = true; reject(err); } } else { resolve(x); } }; //promise 类 class Promise { constructor(executor) { this.status = PENDING; // Promise 的状态 this.value = undefined; // 成功后的值 this.reason = undefined; // 失败后的值 this.onResolvedCallbacks = []; // 成功回调函数集合 this.onRejectedCallbacks = []; // 失败回调函数集合 // Promise 内部提供的 resolve 方法   ,让 Promise 的状态变成成功态             ,并让成功回调执行 const resolve = (value) => { //如果value是Promise则返回value.then的执行结果 if (value instanceof Promise) { return value.then(resolve, reject); } if (this.status === PENDING) { this.status = FULFILLED; this.value = value; this.onResolvedCallbacks.forEach(fn => fn()); } }; // Promise 内部提供的 reject                   ,让 Promise 的状态变成失败态      ,并让失败回调执行 const reject = reason => { if (this.status === PENDING) { this.status = REJECTED; this.reason = reason; this.onRejectedCallbacks.forEach(fn => fn()); } }; // try + catch 只能捕获同步异常 try { //执行入参函数 executor(resolve, reject); } catch(err) { reject(err); } } then(onFulfilled, onRejected) { // 比如.then().then().then(() => {}); 这种调用         ,对可选参数的处理                   ,透传 onFulfilled = typeof onFulfilled === function ? onFulfilled : val => val; // 判断onRejected是否存在或者是否是函数         ,如果不是函数或者不存在      ,我们让它等于一个函数                   ,并且在函数内继续将err向下抛出 onRejected = typeof onRejected === function ? onRejected : err => { throw err }; const promise2 = new Promise((resolve, reject) => { // 同步:成功 if(this.status === FULFILLED) { setTimeout(() => { promise2.resolve = resolve; promise2.reject = reject; try { const x = onFulfilled(this.value); resolvePromise(promise2, x); } catch (err) { reject(err); } }, 0); } // 同步:失败 if (this.status === REJECTED) { setTimeout(() => { promise2.resolve = resolve; promise2.reject = reject; try { const x = onRejected(this.reason); resolvePromise(promise2, x); } catch (err) { reject(err); } }, 0); } // 异步 if (this.status === PENDING) { this.onResolvedCallbacks.push(() => { setTimeout(() => { // 这里需要加上            ,不加上跑测试跑不通 promise2.resolve = resolve; promise2.reject = reject; try { const x = onFulfilled(this.value); resolvePromise(promise2, x); } catch (err) { reject(err); } }); }); this.onRejectedCallbacks.push(() => { setTimeout(() => { promise2.resolve = resolve; promise2.reject = reject; try { const x = onRejected(this.reason); resolvePromise(promise2, x); } catch (err) { reject(err); } }); }); } }); return promise2; } // Promise 中的 catch 指代的就是 then 没有成功回调的一个别名而已 catch(errCallback) { return this.then(null, errCallback); } } // 无论如何都会执行   ,把上一个 then 的结果向下传递                   ,如果 finally 中返回了一个 Promise 会等待这个 Promise 执行完成后继续执行 Promise.prototype.finally = function(callback) { return this.then(val => { return Promise.resolve(callback()).then(() => val); }, (err) => { return Promise.resolve(callback()).then(() => { throw err; }); }); }; // npm install promises-aplus-tests -g // promises-aplus-tests promise.js // 测试自己写的 Promise 是否符合规范的包 Promise.deferred = () => { const dfd = {}; dfd.promise = new Promise((resolve, reject) => { dfd.resolve = resolve; dfd.reject = reject; }); return dfd; }; //Promise.resolve 他会等待里面的 Promise 执行成功 Promise.resolve = val => { return new Promise((resolve) => { resolve(val); }); }; //Promise.reject 不会等待参数中的 Promise 执行完毕 Promise.reject = () => { return new Promise((_, reject) => { reject(val); }); }; //all 方法表示等待所有的 Promise 全部成功后才会执行回调               ,如果有一个 Promise 失败则 Promise 就失败了 Promise.all = promises => { return new Promise((resolve, reject) => { //存放结果 const res = []; //计数,当count 等于 length的时候就resolve let count = 0; const resolveRes = (index, data) => { //将执行结果缓存在res中 res[index] = data; //所有子项执行完毕之后                ,执行resolve 抛出所有的执行结果 if (++count === promises.length) { resolve(res); } }; //循环遍历每一个参数的每一项 for(let i = 0; i < promises.length; i++) { const current = promises[i]; //如果当前项是Promise                  ,则返回 then 的结果 if (isPromise(current)) { current.then((data) => { resolveRes(i, data); }, (err) => { reject(err); }); } else { resolveRes(i, current); } } }); } //race谁是第一个完成的   ,就用他的结果             ,如果是失败这个 Promise 就失败                   ,如果第一个是成功就是成功 Promise.race = (promises) => { return new Promise((resolve, reject) => { for(let i = 0; i < promises.length; i++) { let current = promises[i]; //如果是一个 promise 继续执行 then if (isPromise(current)) { current.then(resolve, reject); } else { //是普通值则直接 resolve 返回      ,并终止循环 resolve(current); break; } } }); } // 专门给 node 的 api 做的 promisify 方法         ,如 fs.readFile Promise.promisify = fn => { return (...arg) => { return new Promise((resolve, reject) => { fn(...arg, (err, data) => { if (err) reject(err); resolve(data); }); }); } }; module.exports = Promise;

1         、Promise 有三个状态:pending      、fulfilled                   ,rejected;pending 代表等待状态         ,也是初始状态;fulfilld 代表成功态;rejected 代表失败态;

2                   、Promise 构造函数内部提供两个方法: resolve 方法      ,如果 value 是 Promise 则返回 value.then 的返回值;如果不是 Promise                    ,修改状态为 fulfilled 并执行成功回调函数;reject 方法修改状态为 rejected 并执行失败回调函数;状态一旦修改不可逆;

3            、每一个 Promise 都有一个 then 方法            ,Promise 的 then 方法返回一个 Promise    ,这就决定了 then 方法的链式调用:

then 方法如果返回一个普通值则直接将这个值传递给下一个 then;

then 方法如果返回一个 Promise 对象                   ,则将 Promise 对象执行结果返回并传递给下一个 then;

resolvePromise 方法主要是处理 x 的值               ,如果是普通值直接返回,如果是 Promise 则返回 x.then 执行的结果;

4   、Promise.prototype.then 方法                ,接收两个参数                  ,第一个是 resolve (成功)回调   ,第二个是 reject (失败)回调;then 源码针对不同的状态进行处理:同步(成功                   、失败)               、异步(pending)操作;

同步:直接借助 setTimeout 来执行相关成功、失败的回调函数;

异步:也是借助 setTimeout 来执行相关成功                、失败的回调函数             ,但是它不是立即执行的                   ,而是将这些回调函数分别存储在 onResolvedCallbacks                  、onRejectedCallbacks 数组中进行订阅      ,在需要的时候执行;

5   、Promise.prototype.catch 方法:和 then 的 reject 回调是一样的         ,支持链式调用;

6             、Promise.prototype.finally 方法:就是一个 then 方法                   ,返回 Promise.resolve 回调         ,作用是把上一个 then 的结果向下传递;

7                   、Promise.resolve      、Promise.reject 方法:返回一个新的 Promise      ,新 Promise 中返回 Promise 里面静态的 resolve 和 reject 方法;

8         、Promise.all 方法:

只有所有的 Promise 都成功了                   ,才会执行 resolve 并返回是所有成功的返回值数组            ,状态为成功状态;

如果有一个 Promise 失败了   ,则会直接执行 reject 返回失败的返回值                   ,状态为失败状态;

有多个 Promise 失败               ,则返回第一个失败的返回值;

9                   、Promise.race 方法:

谁第一个完成就返回谁的结果,如果第一个是失败这个 Promise 就失败                ,如果第一个是成功就是成功;

还有两个方法我们基本用不到                  ,这里就不介绍了      。

声明:本站所有文章   ,如无特殊说明或标注             ,均为本站原创发布         。任何个人或组织                   ,在未征得本站同意时      ,禁止复制         、盗用      、采集                   、发布本站内容到任何网站            、书籍等各类媒体平台                   。如若本站内容侵犯了原著者的合法权益         ,可联系我们进行处理         。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
typescript值得学吗(TypeScript 学习笔记(十万字超详细知识点总结)) confkict(conf.exe是什么文件的进程 安全吗 conf进程的详细情况介绍)