这是 JS 原生方法原理探究系列的第十篇文章。...调用将会决定最终返回的 promise 的状态 1)大致思路 实现 resolvePromise 方法的大致思路如下: 首先判断回调函数的返回值 x 是否等于调用 then 之后的返回值 promise2...可以看到,回调函数的返回值 x 是一个 thenable 的时候,调用 then 之后返回的 promise 会沿用 x 的 value 或者 reason。...不管 x 的状态是否落定,它总会在某一个时刻基于自己的状态去调用 resolve 或者 reject,而且也会传入 x 的 value 或者 reason,这样就相当于我们调用了 resolve(value...说得很清楚了,A+ 规范只是明确了回调函数必须是异步执行的,并没有要求它必须是微任务或者宏任务。也就是说,依赖宏任务去实现 Promise 也是没有问题的,理论上也可以通过 A+ 测试。
Promise 的决议程序主要做了 4 件事: 判断 x 和 promise 是否指向同一个对象; 判断 x 是否是一个 promise 实例; 判断是否是 thenable; x 为其他 js 基础值...Promise) { return x.then(resolve, reject); } // 3.3 判断是否是thenable // Promises/A+:2.3.3...从大的方面来说,then方法中主要做了 2 件事: 处理 onFulfilled 或者 onRejected 不是函数的情况; 创建并返回一个新的 promise 实例; 2.1 利用包装函数将 onFulfilled...创建并返回一个新的 promise 实例; // Promises/A+:2.2.7 then函数必须返回一个promise实例; return new Promise((resolve, reject...静态方法 5.1 Promise.resolve // 如果Promise.resolve接收到的是一个promise,则会直接返回这个promise;否则,则会进一步执行决议操作。
两者的返回值均作为Promise对象单向链表中下一个Promise对象的状态转换事件处理函数的入参。而then方法的返回值是一个新的Promise对象并且已添加到Promise对象单向链表的末尾。...类方法 Promise Promise.resolve({Any} obj) ,用于将非Promise类型的入参封装为Promise对象,若obj为非thenable对象则返回状态为fulfilled...5. thenable对象 拥有 then方法 的对象均称为thenable对象,并且thenable对象将作为Promise对象被处理。...由于源码中加入性能优化的代码,因此我提出核心逻辑以便分析: // 将非thenable对象构造为thenable对象 // 其then方法则返回一个真正的Promise对象 function ValuePromise...return; } } args[i] = val; // 检测是否所有入参都已返回值
onFulfilled 和 onRejected 可以缺省 * 8. promise 可以then多次,promise 的then 方法返回一个 promise * 9....; 有专门的测试脚本可以测试所编写的代码是否符合PromiseA+的规范。...: promises-aplus-tests promise.js promises-aplus-tests中共有872条测试用例。...PromiseA+的规范(翻译版) PS: 下面是我翻译的规范,供参考 术语 promise 是一个有then方法的对象或者是函数,行为遵循本规范 thenable 是一个有then方法的对象或者是函数...如果 value 是个 thenable 对象,返回的promise会“跟随”这个thenable的对象,采用它的最终状态 如果传入的value本身就是promise对象,那么Promise.resolve
在我们不清楚返回的是否是 Promise 实例的情况下,就可以使用 Promise.resolve 进行包装: Promise.resolve(getNameById(id)).then(name =>...(2)参数是一个 thenable 对象 thenable 对象指的是具有 then 方法的对象,比如下面这个对象。...Promise 对象,然后就立即执行 thenable 对象的 then方法。...(3)参数不是具有 then 方法的对象,或根本就不是对象 如果参数是一个原始值,或者是一个不具有then方法的对象,则 Promise.resolve 方法返回一个新的 Promise 对象,状态为...Promise 对象中,同时返回一个新的 Promise 对象,以便可以链式调用。
我们其实让then方法最后不再返回自身实例,而是返回一个新的promise即可,我们可以叫它bridgePromise,它最大的作用就是衔接后续操作,我们看下具体实现代码: MyPromise.prototype.then...状态,就在它的then方法里继续执行resolvePromise解析它的结果,直到返回值不是一个pending状态的promise为止 if (x.status === PENDING)...1.npm i -g promises-aplus-tests 2.promises-aplus-tests mypromise.js 运行测试用例可以看到,我们上面写的promise代码通过了完整的Promises...这一条标准对应的其实是thenable对象,什么是thenable对象,只要有then方法就是thenable对象,然后我们实现的时候照着规范实现就可以了。 else if (x !...它的作用就是将异步回调函数api转换为promise形式,比如下面这个,对fs.readFile 执行promiseify后,就可以直接用promise的方式去调用读取文件的方法了,是不是很强大。
如果这个值是一个 promise ,那么将返回这个 promise ;如果这个值是thenable(即带有"then" 方法),返回的promise会“跟随”这个thenable的对象,采用它的最终状态...当你有多个彼此不依赖的异步任务成功完成时,或者你总是想知道每个promise的结果时,通常使用它。相比之下,Promise.all() 更适合彼此相互依赖或者在其中任何一个reject时立即结束。...(将非Promise值,转换为Promise并当做成功)只要传入的迭代对象中的任何一个 promise 变成成功(resolve)状态,或者其中的所有的 promises 都失败,那么返回的 promise...were rejected// AggregateError: All promises were rejected// 很快完成实现race方法Promise.race(iterable) 方法返回一个...的结果是否成功,都要等结果返回完毕之后执行then方法 race() 只要有一个Promise有了结果,就决定了最终新
一般总是建议,Promise 对象后面要跟catch方法,这样可以处理 Promise 内部发生的错误。catch方法返回的还是一个 Promise 对象,因此后面还可以接着调用then方法。...从上面的实现还可以看到,finally方法总是会返回原来的值。...**该方法返回的新的 Promise 实例,一旦结束,状态总是fulfilled,不会变成rejected。...# Promise.try() 实际开发中,经常遇到一种情况:不知道或者不想区分,函数f是同步函数还是异步操作,但是想用 Promise 来处理它。...因为这样就可以不管f是否包含异步操作,都用then方法指定下一步流程,用catch方法处理f抛出的错误。一般就会采用下面的写法。
还有另外一种概念化Promise的方式是,将它看作一个 未来值,一个与时间无关的值的容器。无论底层的值是否是最终值,这种容器都可以被同样地推理。...Thenables Promise是Promise(..)构造器的纯粹实例。然而,还存在称为 thenable 的类promise对象,它通常可以与Promise机制协作。...一般来说,如果你从某些其他系统收到一个声称是promise或thenable的东西,你不应当盲目地相信它。在下一节中,我们将会看到一个ES6 Promise的工具,它可以帮助解决信任的问题。...它返回一个promise,这个promise会在所有的值完成时完成,或者在这些值中第一个被拒绝的值出现时被立即拒绝。...这是一个奇怪的不一致,我建议你应当永远不要使用空数组调用这些方法。 Generators + Promises 将一系列promise在一个链条中表达来代表你程序的异步流程控制是 可能 的。
index.js 在手写过程中,如果遇到某些地方不理解的情况,可以根据控制台中爆红的提示,在promises-aplus-tests 定位相应的测试用例,便于加深理解 1· 基本使用 首先呢,先来看看比较常用的写法...Promise作为构造函数时,会将一个函数作为它的参数传入 并且Promise是一个含有 then方法的函数 基于此,先写一个最基本的 const PENDING = "pending"; const...2.多次调用.then 我们知道,Promise是可以多次调用then方法的,例如 let p = new Promise((res) => { queueMicrotask(() => {...().then(dothing1).then(dothing2) 这种调用已经非常常见了,本质上是每次执行then方法后都返回一个新的Promise(注:是新的Promise,不再是初始的那个) let...所以我们需要对此进行递归调用; 6. x 是一个 thenable 首先,Promise规范给出的的 thenable定义 'thenable' 是一个定义then方法的对象或者函数 我们先来举几个栗子
如果返回的结果是个 promise,则需要等它完成之后再触发新 promise 的 resolve,所以可以在其结果的 then 里调用新 promise 的 resolvethen(onFulfilled...不带参数为GET请求}实现Promise相关方法实现Promise的resolve实现 resolve 静态方法有三个要点:传参为一个 Promise, 则直接返回它。...,或者您总是想知道每个promise的结果时,通常使用它。...全部处理完成后我们可以拿到每个Promise的状态, 而不管其是否处理成功。...测试写的promise是否规范// 全局安装 cnpm i -g promises-aplus-tests// 命令行执行 promises-aplus-tests promise.js// 测试入口
Promise代表一个目前还不可用,但是在未来的某个时间点可以被解析的值,它允许以一种同步的方式来编写异步代码。...这种 thenable 的特性使得 Promise 的实现更具有通用性:只要其暴露出一个遵循 Promise/A+ 协议的 then 方法即可;这同时也使遵循 Promise/A+ 规范的实现可以与那些不太规范但可用的实现能良好共存...如果 then 不是函数,以 x 为参数执行 promise 如果 x 不为对象或者函数,以 x 为参数执行 promise 如果一个 promise 被一个循环的 thenable 链中的对象解决,...算法虽不强制要求,但也鼓励施者检测这样的递归是否存在,若检测到存在则以一个可识别的 TypeError 为据因来拒绝 promise Promises规范 到目前为止Promises指定了A、B、D、...isPromise(value) Boolean 判断一个对象是否是 promise。 method(name String) 获得一个返回 name 对应方法的 promise 。
Promise代表一个目前还不可用,但是在未来的某个时间点可以被解析的值,它允许以一种同步的方式来编写异步代码。...这种 thenable 的特性使得 Promise 的实现更具有通用性:只要其暴露出一个遵循 Promise/A+ 协议的 then 方法即可;这同时也使遵循 Promise/A+ 规范的实现可以与那些不太规范但可用的实现能良好共存...如果 then 不是函数,以 x 为参数执行 promise 如果 x 不为对象或者函数,以 x 为参数执行 promise 如果一个 promise 被一个循环的 thenable 链中的对象解决,...算法虽不强制要求,但也鼓励施者检测这样的递归是否存在,若检测到存在则以一个可识别的 TypeError 为据因来拒绝 promise Promises规范 到目前为止Promises指定了A、B、D、A...isPromise(value) Boolean 1 判断一个对象是否是 promise。 method(name String) 获得一个返回 name 对应方法的 promise 。
一般总是建议,Promise 对象后面要跟catch()方法,这样可以处理 Promise 内部发生的错误。...从上面的实现还可以看到,finally方法总是会返回原来的值。...该方法返回的新的 Promise 实例,一旦发生状态变更,状态总是fulfilled,不会变成rejected。...Promise.try() 实际开发中,经常遇到一种情况:不知道或者不想区分,函数f是同步函数还是异步操作,但是想用 Promise 来处理它。...因为这样就可以不管f是否包含异步操作,都用then方法指定下一步流程,用catch方法处理f抛出的错误。一般就会采用下面的写法。
原理是通过判断是否到达一定时间来触发函数。实现Promise相关方法实现Promise的resolve实现 resolve 静态方法有三个要点:传参为一个 Promise, 则直接返回它。...传参为一个 thenable 对象,返回的 Promise 会跟随这个对象,采用它的最终状态作为自己的状态。其他情况,直接返回以该值为成功状态的promise对象。...,或者您总是想知道每个promise的结果时,通常使用它。...全部处理完成后我们可以拿到每个Promise的状态, 而不管其是否处理成功。...测试写的promise是否规范// 全局安装 cnpm i -g promises-aplus-tests// 命令行执行 promises-aplus-tests promise.js// 测试入口
{ promises[i].then(resolve, reject) } })}复制代码手写 Promise.race该方法的参数是 Promise 实例数组, 然后其 then...在这个对象上使用 open 方法创建一个 HTTP 请求,open 方法所需要的参数是请求的方法、请求的地址、是否异步和用户的认证信息。在发起请求前,可以为这个对象添加一些信息和监听函数。...比如说可以通过 setRequestHeader 方法来为请求添加头信息。还可以为这个对象添加一个状态监听函数。...一个 XMLHttpRequest 对象一共有 5 个状态,当它的状态变化时会触发onreadystatechange 事件,可以通过设置监听函数,来处理请求成功后的结果。...当对象的 readyState 变为 4 的时候,代表服务器返回的数据接收完成,这个时候可以通过判断请求的状态,如果状态是 2xx 或者 304 的话则代表返回正常。
对象,那么我们就知道,浏览器的js引擎里已经有了 Promise 队列,这样就可以利用 Promise 将任务放在它的队列中去。...一般总是建议,Promise 对象后面要跟catch()方法,这样可以处理 Promise 内部发生的错误。...从上面的实现还可以看到,finally方法总是会返回原来的值。...该方法返回的新的 Promise 实例,一旦发生状态变更,状态总是fulfilled,不会变成rejected。...因为这样就可以不管f是否包含异步操作,都用then方法指定下一步流程,用catch方法处理f抛出的错误。一般就会采用下面的写法。
所谓Promise,字面上可以理解为“承诺”,就是说A调用B,B返回一个“承诺”给A,然后A就可以在写计划的时候这么写:当B返回结果给我的时候,A执行方案S1,反之如果B因为什么原因没有给到A想要的结果...事实上,Promise规范没有要求这样做,你甚至可以不做任何的处理(即不传入then的第二个参数)或者统一处理。...”转到“完成”态或者“拒绝”态,不能逆向转换,同时“完成”态和“拒绝”态不能相互转换 promise必须实现then方法(可以说,then就是promise的核心),而且then必须返回一个promise...同时,then可以接受另一个promise传入,也接受一个“类then”的对象或方法,即thenable对象。 可以看到,Promise规范的内容并不算多,大家可以试着自己实现以下Promise。...在这里,Promise.resolve(v)静态方法只是简单返回一个以v为肯定结果的promise,v可不传入,也可以是一个函数或者是一个包含then方法的对象或函数(即thenable)。
领取专属 10元无门槛券
手把手带您无忧上云