理解Promise (4)
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
- f/when
resolvePromise
is called with a valuey
, run[[Resolve]](promise, y)
. - If/when
rejectPromise
is called with a reasonr
, rejectpromise
withr
. - If both
resolvePromise
andrejectPromise
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)相关推荐
- 大白话讲解Promise(二)理解Promise规范
上一篇我们讲解了ES6中Promise的用法,但是知道了用法还远远不够,作为一名专业的前端工程师,还必须通晓原理.所以,为了补全我们关于Promise的知识树,有必要理解Promise/A+规范,理解 ...
- es5如何实现promise_彻底理解Promise对象——用es5语法实现一个自己的Promise(上篇)...
众所周知javascript语言的一大特色就是异步,这既是它的优点,同时在某些情况下也带来了一些的问题.最大的问题之一,就是异步操作过多的时候,代码内会充斥着众多回调函数,乃至形成回调金字塔.为了解决 ...
- 理解Promise的3种姿势
对于Promise,也许你会用了,却并不理解:也许你理解了,却只可意会不可言传.这篇博客将从3个简单的视角理解Promise,应该对你有所帮助. 示例1中,asyncFunc()函数返回的是一个Pro ...
- 通俗浅显的理解promise中的then
通俗浅显的理解promise中的then 先看一下下面4个Promise到底有什么区别呢? 执行第一个方法: 执行第二个方法: 执行第三个方法: 执行第四个方法: 文章原文出处:博主petruslaw ...
- 深入理解Promise并写一个符合Promise a+规范的Promise代码
深入理解Promise并写一个符合Promise a+规范的Promise代码 关于Promise函数可以参考我写的这篇文章https://www.cnblogs.com/qiaohong/p/770 ...
- ES6——举个例子理解Promise的原理和使用
1. Promise 之前 1.1 回调函数 回调函数:把函数A当作参数传递给另一个函数B调用,那么A就是回调函数. 一些例子 具名回调 function 你有几只狗(fn){fn('一只狗') } ...
- 理解promise、async 和await之间的执行关系
先看下面的例子 console.log('script start'); async function async1(){console.log('async1 start');await async ...
- 一篇文章理解Promise原理
前提掌握知识: 微任务包括: MutationObserver.Promise.then()或reject().Promise为基础开发的其它技术,比如fetch API.V8的垃圾回收过程.Node ...
- 理解promise、promise.all、promise.race
文章目录 promise promise.all promise.race 注意 总结 promise Promise 对象代表了未来将要发生的事件,用来传递异步操作的消息. Promise 对象有以 ...
最新文章
- 刘宇与小白健康:一个理想主义者的互联网“众包”实践
- VS2005工程增加SDK
- MathType可以在Word、PPT中插入矩阵吗
- python12岁_12岁。Python操作Excel,12Python,excel
- 《Python Cookbook 3rd》笔记汇总
- 深入了解Java的SPI机制
- pytorch Alexnet
- 给定一个N位数,得到一个N-k位的数中最小的数
- 鸿星尔克因公司系统崩溃、恳请顾客退款;乔布斯首份手写求职信拍卖出222万;OpenAI 开源 Triton语言|极客头条...
- node.js学习笔记之浅谈观察者模式
- delphi 去掉字符串中所有的标点符号_[话俾你知]Python使用正则处理字符串技巧(分割、替换)...
- Rust: 在子线程启动子线程
- java8判断对象是否为空新写法
- 学Python好找工作吗?需要满足Python岗位哪些要求?
- Allegro PCB Design GXL (legacy) - 更新 PCB 中的元件封装
- 微信小程序踩坑之旅(三):不同机型布局适配问题(rpx,px,vh,vw)
- 2013年H1B携H4签证
- pandas to_json为一行 一个json对象的格式
- moment.js获取当天,本周,当月,当季,近n天开始结束时间
- md5加密工具类cookie登陆验证