then 方法必须 返回一个新的promise

promise2 = promise1.then(onFulfilled, onRejected);

新的Promise 必须返回传递两个方法  onFulfilled, onRejected

If either onFulfilled or onRejected returns a value x, run the Promise Resolution Procedure [[Resolve]](promise2, x).

onFulfilled, onRejected  其中的某个都要返回 一个value

if either onFulfilled or onRejected returns a value x, run the Promise Resolution Procedure [[Resolve]](promise2, x)

如果onfulled或onrejected返回值x,请运行承诺解决过程[[解决]](promise2,x)。

 let x = onfulfilled(this.value);// x是普通值还是promise 如果是普通值 直接调用promise2的resolve// 如果是promise  那应该让x这个promise执行 x.thenresolvePromise(promise2,x,resolve,reject);

这段代码是  resolvePromise    承诺解决过程

resolvePromise  这个函数里面 有Promise 这个参数,所以我们要拿到这个值 但是我们直接打印出来这个值 是 underfind 所以我们要用 promise2

这样,我们做到这里的时候  then 方法的大概结构就出来了

 then(onfulfilled,onrejected){ let promise2;promise2 = new Promise((resolve,reject)=>{if(this.status === 'fulfilled'){setTimeout(()=>{ try{let x = onfulfilled(this.value);// x是普通值还是promise 如果是普通值 直接调用promise2的resolve// 如果是promise  那应该让x这个promise执行 x.then
                        resolvePromise(promise2,x,resolve,reject);}catch(e){reject(e);}},0);}if(this.status === 'rejected'){setTimeout(()=>{try{let x = onrejected(this.reason);resolvePromise(promise2,x,resolve,reject);}catch(e){reject(e);}},0)}if(this.status === 'pending'){this.resolveCallbacks.push(()=>{setTimeout(()=>{try{let x = onfulfilled(this.value);resolvePromise(promise2,x,resolve,reject);}catch(e){reject(e);}},0)});this.rejectCallbacks.push(()=>{setTimeout(()=>{try{let x = onrejected(this.reason);resolvePromise(promise2,x,resolve,reject);}catch(e){reject(e);}},0)})}});return promise2}

接下来我们来处理   The Promise Resolution Procedure  的问题

If promise and x refer to the same object, reject promise with a TypeError as the reason.

let  resolvePromise = (promise2,x,resolve,reject) => {if(promise2 === x){return reject(new TypeError('循环引用'))}
}

if x is an object or function,

   if(typeof x === 'function' || (typeof x === 'object' && x !== null)){}

Let then be x.then

  let then = x.then; // 如果取then方法出错 那就用错误拒绝promise2

  1. f/when resolvePromise is called with a value y, run [[Resolve]](promise, y).
  2. If/when rejectPromise is called with a reason r, reject promise with r.
  3. If both resolvePromise and rejectPromise are called, or multiple calls to the same argument are made, the first call takes precedence, and any further calls are ignored.
 if(typeof then === 'function'){ // 我就认为他是一个promisethen.call(x,y=>{ // 让当前的promise执行 ,不用多次取then方法了// y 有可能还是一个promise , 继续调用resolvePromise方法,直到解析出一个常量为止,最终把常量传递下去if(called) return; // 放置此方法多次被调用called = true;resolvePromise(promise2,y,resolve,reject);},r=>{if(called) return;called = true;reject(r); // 让当前的promise变成失败态即可
                })}else{// x就是一个普通的对象 并没有then方法
                resolve(x);}

全部的代码:

let  resolvePromise = (promise2,x,resolve,reject) => {// 判断x的类型 来处理promise2是成功还是失败// 所有的promise都遵循这个规范,不同的人写的promise可能会混用// 尽可能考虑的周全 要考虑别人promise可能出错的情况if(promise2 === x){return reject(new TypeError('循环引用'))}// 判断x是不是一个promise  ,这个x 可能不是自己的promise 所以为了安全 需要在进行校验,放置调一起用成功和失败 if(typeof x === 'function' || (typeof x === 'object' && x !== null)){// 尝试取当前x的then方法, 这个then方法可能别人定义的时候 用的Object.defineProperty
        let called;try{let then = x.then; // 如果取then方法出错 那就用错误拒绝promise2if(typeof then === 'function'){ // 我就认为他是一个promisethen.call(x,y=>{ // 让当前的promise执行 ,不用多次取then方法了// y 有可能还是一个promise , 继续调用resolvePromise方法,直到解析出一个常量为止,最终把常量传递下去if(called) return; // 放置此方法多次被调用called = true;resolvePromise(promise2,y,resolve,reject);},r=>{if(called) return;called = true;reject(r); // 让当前的promise变成失败态即可
                })}else{// x就是一个普通的对象 并没有then方法
                resolve(x);}}catch(e){if(called) return;called = true;reject(e);}}else{// x肯定一个常量
        resolve(x);}
}class Promise{constructor(executor){this.status = 'pending'; this.value; this.reason;this.resolveCallbacks = []; // 当then是pending 我希望吧成功的方法都放到数组中this.rejectCallbacks = [];let resolve = (value)=>{if(this.status == 'pending'){this.status = 'fulfilled';this.value = value;this.resolveCallbacks.forEach(fn=>fn()); // 发布
            }}let reject = (reason)=>{if(this.status === 'pending'){this.status = 'rejected';this.reason = reason;this.rejectCallbacks.forEach(fn=>fn())}}try{executor(resolve,reject);}catch(e){reject(e);}}then(onfulfilled,onrejected){ let promise2;promise2 = new Promise((resolve,reject)=>{if(this.status === 'fulfilled'){setTimeout(()=>{ try{let x = onfulfilled(this.value);// x是普通值还是promise 如果是普通值 直接调用promise2的resolve// 如果是promise  那应该让x这个promise执行 x.then
                        resolvePromise(promise2,x,resolve,reject);}catch(e){reject(e);}},0);}if(this.status === 'rejected'){setTimeout(()=>{try{let x = onrejected(this.reason);resolvePromise(promise2,x,resolve,reject);}catch(e){reject(e);}},0)}if(this.status === 'pending'){this.resolveCallbacks.push(()=>{setTimeout(()=>{try{let x = onfulfilled(this.value);resolvePromise(promise2,x,resolve,reject);}catch(e){reject(e);}},0)});this.rejectCallbacks.push(()=>{setTimeout(()=>{try{let x = onrejected(this.reason);resolvePromise(promise2,x,resolve,reject);}catch(e){reject(e);}},0)})}});return promise2}
}
module.exports = Promise;

https://promisesaplus.com/

转载于:https://www.cnblogs.com/guangzhou11/p/11307074.html

理解Promise (4)相关推荐

  1. 大白话讲解Promise(二)理解Promise规范

    上一篇我们讲解了ES6中Promise的用法,但是知道了用法还远远不够,作为一名专业的前端工程师,还必须通晓原理.所以,为了补全我们关于Promise的知识树,有必要理解Promise/A+规范,理解 ...

  2. es5如何实现promise_彻底理解Promise对象——用es5语法实现一个自己的Promise(上篇)...

    众所周知javascript语言的一大特色就是异步,这既是它的优点,同时在某些情况下也带来了一些的问题.最大的问题之一,就是异步操作过多的时候,代码内会充斥着众多回调函数,乃至形成回调金字塔.为了解决 ...

  3. 理解Promise的3种姿势

    对于Promise,也许你会用了,却并不理解:也许你理解了,却只可意会不可言传.这篇博客将从3个简单的视角理解Promise,应该对你有所帮助. 示例1中,asyncFunc()函数返回的是一个Pro ...

  4. 通俗浅显的理解promise中的then

    通俗浅显的理解promise中的then 先看一下下面4个Promise到底有什么区别呢? 执行第一个方法: 执行第二个方法: 执行第三个方法: 执行第四个方法: 文章原文出处:博主petruslaw ...

  5. 深入理解Promise并写一个符合Promise a+规范的Promise代码

    深入理解Promise并写一个符合Promise a+规范的Promise代码 关于Promise函数可以参考我写的这篇文章https://www.cnblogs.com/qiaohong/p/770 ...

  6. ES6——举个例子理解Promise的原理和使用

    1. Promise 之前 1.1 回调函数 回调函数:把函数A当作参数传递给另一个函数B调用,那么A就是回调函数. 一些例子 具名回调 function 你有几只狗(fn){fn('一只狗') } ...

  7. 理解promise、async 和await之间的执行关系

    先看下面的例子 console.log('script start'); async function async1(){console.log('async1 start');await async ...

  8. 一篇文章理解Promise原理

    前提掌握知识: 微任务包括: MutationObserver.Promise.then()或reject().Promise为基础开发的其它技术,比如fetch API.V8的垃圾回收过程.Node ...

  9. 理解promise、promise.all、promise.race

    文章目录 promise promise.all promise.race 注意 总结 promise Promise 对象代表了未来将要发生的事件,用来传递异步操作的消息. Promise 对象有以 ...

最新文章

  1. 刘宇与小白健康:一个理想主义者的互联网“众包”实践
  2. VS2005工程增加SDK
  3. MathType可以在Word、PPT中插入矩阵吗
  4. python12岁_12岁。Python操作Excel,12Python,excel
  5. 《Python Cookbook 3rd》笔记汇总
  6. 深入了解Java的SPI机制
  7. pytorch Alexnet
  8. 给定一个N位数,得到一个N-k位的数中最小的数
  9. 鸿星尔克因公司系统崩溃、恳请顾客退款;乔布斯首份手写求职信拍卖出222万;OpenAI 开源 Triton语言|极客头条...
  10. node.js学习笔记之浅谈观察者模式
  11. delphi 去掉字符串中所有的标点符号_[话俾你知]Python使用正则处理字符串技巧(分割、替换)...
  12. Rust: 在子线程启动子线程
  13. java8判断对象是否为空新写法
  14. 学Python好找工作吗?需要满足Python岗位哪些要求?
  15. Allegro PCB Design GXL (legacy) - 更新 PCB 中的元件封装
  16. 微信小程序踩坑之旅(三):不同机型布局适配问题(rpx,px,vh,vw)
  17. 2013年H1B携H4签证
  18. pandas to_json为一行 一个json对象的格式
  19. moment.js获取当天,本周,当月,当季,近n天开始结束时间
  20. md5加密工具类cookie登陆验证

热门文章

  1. 使用Postgrest快速创建数据库的OpenAPI接口
  2. CTFshow php特性 web133
  3. CTFshow php特性 web123
  4. arcLength函数
  5. Pandas通过某列不是NaN来进行筛选
  6. 爬虫为什么用Chrome?
  7. cdoj 1070 秋实大哥打游戏 带权并查集
  8. 转】MYSQL性能调优与架构设计之select count(*)的思考
  9. (转载)H.264码流的RTP封包说明
  10. 4月13日学习笔记——jQuery动画