resolve和reject函数被调用时,分别将promise的状态改为完成fulfilled或失败rejected。...如果在executor函数中抛出一个错误,那么该promise状态为rejected,executor函数的返回值被忽略。 状态 pending: 初始状态,既不是成功,也不是失败状态。...",rand); // reject回调执行 }) 方法 Promise.all(iterable) 这个方法返回一个新的promise对象,该promise对象在iterable参数对象里所有的promise...这个新的promise对象在触发成功状态以后,会把一个包含iterable里所有promise返回值的数组作为成功回调的返回值,顺序跟iterable的顺序保持一致;如果这个新的promise对象触发了失败状态...Promise.prototype.finally(onFinally) 添加一个事件处理回调于当前promise对象,并且在原promise对象解析完毕后,返回一个新的promise对象。
这让异步方法可以像同步方法那样返回值,但并不是立即返回最终执行结果,而是一个能代表未来出现的结果的 Promise 对象。 Promise 对象有以下两个特点: 对象的状态不受外界影响。...; }); 上面代码中,不管 promise 最后的状态,在执行完 then 或 catch 指定的回调函数以后,都会执行 finally 方法指定的回调函数。...(1)只有 p1、p2 的状态都变成 fulfilled,p 的状态才会变成 fulfilled,此时 p1、p2 的返回值组成一个数组,传递给 p 的回调函数。...(2)只要 p1、p2 之中有一个被 rejected,p 的状态就变成 rejected,此时第一个被 reject 的实例的返回值,会传递给 p 的回调函数。...那个率先改变的 Promise 实例的返回值,就传递给 p 的回调函数。
而通过事件交互会多做一些工作,比如发送事件,监听事件,事件回调等操作。而Promise能够获取异步操作的结果,这样的话,方便进一步处理接下来的逻辑。...Promise.prototype.then Promise实例具有then方法,then方法是定义在Promise.prototype上的,它的作用是为Promise实例添加状态回调改变时的回调函数。...(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、 p2、 p3的返回值组成一个数组,传递给p的回调函数。...那个率先改变的Promise实例的返回值, 就传递给p的回调函数。...不带有任何参数 Promise.resolve允许在调用时,不带任何参数。而直接返回一个Resolved状态的Promise对象。
实现分析 从后往前看,首先MyPromise实例拥有then方法,而传入then的回调一定是晚于resolve执行的,因此这里通过闭包将then的回调存起来,等待被调用。...then早于resolve调用时:此时状态值仍是pending,因此可以保存onResolve回调,等待resolve调用 resolve早于then调用时:保存决议值,状态流转为resolved;等待...反解内部的promise then未传入任何回调,透传上一promise决议值 第一题 为什么finalHandler的执行顺序在doSomethingElse之后?...finalHandler是then2的onResolve回调,等待的是then1生成的promise。而then1生成的promise的决议值是doSomethingElse()的返回值。...第三题 doSomethingElse()返回值是一个promise,不能作为then1的onResolve回调,因此这种情况相当于then未传入任何回调,这时会将doSomething的决议值透传到then2
为了解决回调函数的弊端,引入了 promise,它俩之间的关键区别是什么时候使用回调,我们可以向函数中传递一个回调,然后等到执行回调函数后可以得到结果。...而在 promise 中,我们是在 promise 的返回值中使用回调。 优势 1....Promise 和 回调函数当在异步操作中使用时,都是为了解决相同的问题;Promise 加了一层抽象使得代码更整洁、函数化以及更少的错误发生; 2....我们不需要知道将使用异步操作返回的值的回调; 3. Promise 是链式调用可以是代码结构扁平化而不会引起回调地狱问题; 4....Resolve promise 为了完成异步任务,时间是不固定的。当异步任务还在执行的时候,promise 处在 pending 状态。一旦完成它将返回值(通常是从异步任务返回的)。
Promise的实例 这点儿很重要 所以说调用一个async函数时,可以理解为里边的代码都是处于new Promise中,所以是同步执行的 而最后return的操作,则相当于在Promise中调用resolve...但实际上,我们会直接获得返回值:1,也就是说,如果在Promise中返回一个Promise,实际上程序会帮我们执行这个Promise,并在内部的Promise状态改变时触发then之类的回调。...Promise let number = getNumber() console.log(number) // Promise 所以在使用时一定要切记await关键字 let number = await...getNumber() console.log(number) // 1 不是所有的地方都需要添加await 在代码的执行过程中,有时候,并不是所有的异步都要添加await的。...这是因为forEach并不会关心回调函数的返回值是什么,它只是运行回调。
实际上Promise的用法非常简单,自己不太理解的只是then() finally() catch()在链式调用时缺省回调函数的情况 Description Promise像某个值的代理,该值在promise...它使得异步方法像同步方法一样返回值:但它并不完全像同步方法一样直接返回值,而是通过返回一个promise实例,在未来的某个时候呈现返回值。 Promise和promise不是一个概念。...大写的代表某个类,小写的表示某个具体的实例 Promise总是在以下3种状态中变动: pending 初始状态 fulfilled 表示某项操作(方法)成功 rejected 表示某项操作失败 一个处于...需要特别说明的是:当then()缺少一个回调函数时,链式调用不会被影响,将会继续执行下一个动作(上一个then()的返回值作为下一个then()的入参)。...的入参是第一个rejected 的promise对象的reject时的返回值 const promise1 = Promise.resolve(3); const promise2 = 42; const
手动实现Promise JavaScript是单线程的语言,通过维护执行栈与任务队列而实现了异步操作,setTimeout与Ajax就是典型的异步操作,Promise就是异步操作的一个解决方案,用于表示一个异步操作的最终完成或失败...resolve和reject函数被调用时,分别将promise的状态改为完成fulfilled或失败rejected。...如果在executor函数中抛出一个错误,那么该promise状态为rejected,executor函数的返回值被忽略。...状态 Promise本质上就是一个状态机,完整的说是有限状态自动机,给定当前输入与状态,那么输出是可以明确计算的。 pending: 初始状态,既不是成功,也不是失败状态。...,而setTimeout的回调是置于宏队列 try { this.onFulfilled.forEach(handler); // 交予事件处理
在此期间,Promise 对象将扮演一个真实数据的代理角色。接下来,你可以在 Promise 对象上绑定一个回调函数,一旦真实数据变得可用这个回调函数将会被调用。...当 resolve(value) 方法被第一次调用时,promise 属性的状态变成 完成,所有之前或之后观察该 promise 的 promise 的状态都被转变成 完成。...实现一个迷你版本的Promise 上面扯了这么多规范,现在我们看看如何实现一个简单而短小的Promise。...此外,在 Promises/A 规范中,由 then 方法生成的 Promise 对象是已执行还是已拒绝,取决于由 then 方法调用的那个回调是返回值还是抛出错误。...在 JQuery 的 Promise 对象的回调中抛出错误是个糟糕的主意,因为错误不会被捕获。
// Promises/A+:2.2.7.3 如果onFulfilled不是函数,而promise1已经是fulfilled, // 则promise2必须用promise1的决议值进行决议,所以这里需要添加...onFulfilled : (value) => value; // Promises/A+:2.2.7.4 如果onRejected不是函数,而promise1已经是rejected, //...5.3 Promise.race // 需要注意的是,如果Promise.race接收到的是一个空数组([]),则会一直挂起,而不是立即决议。...因为要保持返回值和接收到的promise的位置一致性。...因为要保持返回值和接收到的promise的位置一致性。
返回的不是promise, 返回promise为成功, value就是返回值 */ try { const result = callback...返回的不是promise, 返回promise为成功, value就是返回值 resolve(result) } } catch...内部立即同步回调,异步操作在执行器中执行(executor 函数在Promise构造函数返回所建promise实例对象前被调用) resolve 和 reject 函数被调用时,分别将promise的状态改为...}); 返回值:当一个 Promise 完成(fulfilled)或者失败(rejected)时,返回函数将被异步调用(由当前的线程循环来调度完成)。具体的返回值依据以下规则返回。...}) 在异步函数中抛出的错误不会被catch捕获到 在resolve()后面抛出的错误会被忽略 var p2 = new Promise(function(resolve, reject) { setTimeout
而 [[Resolve]](promise, thenable) 的递归性质又使得其被再次调用,根据上述的算法将会陷入无限递归之中。...当 resolve(value) 方法被第一次调用时, promise 属性的状态变成 完成,所有之前或之后观察该 promise 的 promise 的状态都被转变成 完成。...此外,在 Promises/A 规范中,由 then 方法生成的 Promise 对象是已执行还是已拒绝,取决于由 then 方法调用的那个回调是返回值还是抛出错误。...在 JQuery 的 Promise 对象的回调中抛出错误是个糟糕的主意,因为错误不会被捕获。...最后一个例子揭示了,实现 Promise 的关键是实现好 doResolve 方法,在完事以后触发回调。而为了保证异步 setTimeout(fun, 0); 是关键一步。 附:Promise
只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时,它们的返回值组成一个数组,传递给p的回调函数。 rejected。...只要p1、p2、p3之中有一个被rejected,p的状态就变成了rejected,此时,第一个被reject的实例的返回值,会传递给p的回调函数。...该实例执行完catch方法后,也会变成resolved,导致Promise.all()方法参数里面的两个实例都会resolved,因此会调用then方法指定的回调函数,而不会调用catch方法指定的回调函数...率先改变的Promise实例的返回值,就传递给p的回调函数。 参数:和Promise.all()方法一样,如果不是Promise实例,就会调用Promise.resolve()方法转化。...不带有任何参数 Promise.resolve()方法允许调用时不带参数,直接返回一个resolved状态的Promise对象(没有参数)。
而 [[Resolve]](promise, thenable) 的递归性质又使得其被再次调用,根据上述的算法将会陷入无限递归之中。...当 resolve(value) 方法被第一次调用时, promise 属性的状态变成 完成,所有之前或之后观察该 promise 的 promise 的状态都被转变成 完成。...此外,在 Promises/A 规范中,由 then 方法生成的 Promise 对象是已执行还是已拒绝,取决于由 then 方法调用的那个回调是返回值还是抛出错误。...在 JQuery 的 Promise 对象的回调中抛出错误是个糟糕的主意,因为错误不会被捕获。 ...最后一个例子揭示了,实现 Promise 的关键是实现好 doResolve 方法,在完事以后触发回调。而为了保证异步 setTimeout(fun, 0); 是关键一步。 附:Promise
then函数返回一个新的Promsie对象,它的值取决于回调函数的返回值如果当前状态是pending,需要将onResolved,onRejected回调保存起来,等异步结束之后再执行class MyPromise...// 执行 onRejected 回调函数 const x = onRejected(this.reason); // 处理返回值 resolve(...为什么then函数中需要考虑Promise状态为pending的情况?当 then 方法被调用时,我们首先需要判断原始 Promise 对象的状态。...但是,如果原始 Promise 对象的状态为 pending,那么我们就需要等待原始 Promise 对象的状态发生变化,再执行相应的操作。2. 当then函数传的参数不是函数怎么办?...在调用then函数中,当Promise的状态为pending时候,会把onResolved和onRejected回调放到各自回调函数队列中,等状态改变(即在执行resolve函数/reject函数)时候
而 [Resolve] 的递归性质又使得其被再次调用,根据上述的算法将会陷入无限递归之中。...当 resolve(value) 方法被第一次调用时, promise 属性的状态变成 完成,所有之前或之后观察该 promise 的 promise 的状态都被转变成 完成。...,而 Promises/A 规范的 then 在行为上更像是 jQuery 的 pipe 。...此外,在 Promises/A 规范中,由 then 方法生成的 Promise 对象是已执行还是已拒绝,取决于由 then 方法调用的那个回调是返回值还是抛出错误。...在 JQuery 的 Promise 对象的回调中抛出错误是个糟糕的主意,因为错误不会被捕获。 最后一个例子揭示了,实现 Promise 的关键是实现好 doResolve 方法,在完事以后触发回调。
回调函数队列 catch 方法 task 处理函数和注册的回调处理函数都是使用者在使用 Promise 时,自行根据业务需要编写的代码 那么,剩下的也就是我们在实现 Promise 时需要编写的代码了...答案不是的,网上看了些这类文章,他们的处理是 resolve 调用,状态就变化,就去处理回调队列了 但实际上,这样是错的 状态的变更,其实依赖于 resolve 调用时,传递过去的参数的类型,因为这里可以传递任意类型的值...但内部并不一定就会发生状态变化,只有当 resolve 传递的参数类型既不是 Promise 对象类型,也不是具有 then 方法的 thenable 对象时,状态才会发生变化 而当传递的参数是 Promise...的状态变更是依赖于回调函数的返回值。...,这个新的 Promise 的状态和结果又要依赖于回调函数的返回值,而回调函数的执行又要看情况是缓存进回调函数队列里,还是直接取依赖的 Promise 的状态结果后,丢到微任务队列里去执行 虽然职能复杂是复杂了点
要实现这个特性,实际上可以先判断传给 then 方法的参数是不是函数,如果不是(包含没有传参的情况),那么就自定义一个回调函数: onFulfilled 如果不是函数:定义一个返回 value 的函数,...调用 then 之后返回的 promise 的状态,取决于回调函数的返回值,这部分的逻辑比较复杂,我们会用一个 resolvePromise 函数单独进行处理,而 then 方法内部只负责调用这个方法。...// 这样是会报错的,因为 then 的返回值等于回调函数的返回值 let p = Promise.resolve(1).then(res => p) 接着判断 x 是不是一个非 null 对象或者函数...1)基于宏任务的实现 回调函数的执行逻辑是在 then 方法中编写的,因此只需要修改 then 方法,在原先执行回调函数的逻辑外面包裹上一个 setTimeout 即可: Promise.prototype.then...而 P.resolve(fn()) 将会返回 fn(),也就是 Promise.reject(2),走失败回调的逻辑,注意这里我们没有声明失败回调,所以会采用默认的失败回调, 接受前面 promise
这让异步方法可以像同步方法那样返回值,但并不是立即返回最终执行结果,而是一个能代表未来出现的结果的promise对象。...}); then 方法返回一个 Promise。它最多需要有两个参数:Promise 的成功和失败情况的回调函数。...另外catch无法捕获在异步方法里抛出的异常 finally 方法由于无法知道promise的最终状态,所以finally的回调函数中不接收任何参数,它仅用于无论最终结果如何都要执行的情况。...所以在使用链式调用时要慎重!...,返回的结果也是一个数组,将会按照参数内的 promise 顺序排列,而不是由调用 promise 的完成顺序决定.
领取专属 10元无门槛券
手把手带您无忧上云