写在前面

本文属于对stackoverflow中写法的解析,原文链接:Stack Overflow

如果你在其他环境下遇到同样问题,这个文章可能也会有帮助

问题复现

如何在代码执行过程中获取到promise的状态?

如果你想寻找或尝试通过原生的属性,或者指定API进行访问,基本可以放弃了,我也是看了很多博客的确没找到,如果您找了其他方式,还望指教

解决方式

本文中提到的解决方式主要是继续stackoverflow中提供的解决方式【完整代码】

/**
 * 传入需要测试的 Promise 对象,将对应结果返回
 * @param promise 需要测试的 Promise 对象
 * @return {Promise<string>}
 */
const promiseState = promise => {
	const target = {}
	return Promise.race([promise, target]).then(
			value => (value === target) ? 'pending' : 'fulfilled',
			() => 'rejected',
	)
}

// 测试代码
let a = Promise.resolve();
let b = Promise.reject();
let c = new Promise(() => {});

promiseState(a).then(state => console.log(state)); // fulfilled
promiseState(b).then(state => console.log(state)); // rejected
promiseState(c).then(state => console.log(state)); // pending

这种方式通过promise中的race()方法来进行了状态的判断,非常奇妙的一种方式

代码分析

  1. 在方法中会接收一个promise对象,开始了整个方法

  2. 进入方法后会先创建一个target对象,这个对象只用于后续的匹配,没有其他含义

    const target = {}
    
  3. 然后开始最核心的部分,因为stackoverflow中对代码进行简写,可以先进行代码的还原

    return Promise.race([promise, target]).then(
        			// 成功回调
    				value => {
    					return (value === target) ? 'pending' : 'fulfilled'
    				},
        			// 失败回调
    				() => {
    					return 'rejected'
    				},
    		)
    

    可以复现出这种结构,promiserace开始后,接收两个对象,一个为刚刚创建的target对象,还有一个是接收到的promise对象,当两个其中一个状态结束时,整个Promise.race()结束,这时分为三种情况

    1. 当传入的promisepending状态时,Promise.race会找到最先有确定状态的元素,并将其返回,因为promise没有结束,那么返回值对象会接收到定义的target,因为target的状态是确定的,这时value接收到的值就是已经确定状态的target,如果进行对比,那么他们两个一定是相等的,这时也就是返回pending
    2. 当传入的promisefulfilled状态时,相当于promise已经有确定的值了,Promise.race匹配到第一个直接结束,并将匹配到的内容返回,返回的内容因为是一个全新的对象,对象的内存地址不可能相等,所以判断结果是false,也就返回fulfilled
    3. 当传入的promiserejected状态时,promise状态确定,那么因为状态报错,直接进入catch中,走失败回调,这个回调一旦执行,就可以判定promsie结束,并且内容出现报错,直接返回rejected即可
    4. 在调用的时候,因为返回的时会将对应的状态通过promise返回,所以直接通过调用方法之后的then中指定回调来完成状态的获取
    • 值得注意的是Promise.race()在匹配的过程中,一定保证要判断的promise在前,因为只有当promise状态不确定时才会判断第二个内容的状态,如果将状态已经确定的target放在第一个,那么将不会再进行promise的判断,返回结果永远为fulfilled

    • 并且因为catch有两种形式,可以进行变形,这种形式可能更常见(根据个人习惯了)

      const promiseState = promise => {
      	const target = {}
      	return Promise.race([promise, target]).then(
      			value => {
      				return (value === target) ? 'pending' : 'fulfilled'
      			},
      	).catch(() => {
      		return 'rejected'
      	})
      }
      

本文仅代表鄙人粗鄙的拙见,可能出现疏忽和纰漏,如果您发现了问题还望与我沟通联系,谢谢。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐