关于代码中Promise工作机制及两种返回方式差异的技术咨询
让我来逐个解答你的问题:
问题1:当getRemoteProfile不返回Promise.resolve(null)时,链式调用的then会发生什么?
当!id && /^_/.test(id)这个条件不满足时,getRemoteProfile会走后面的分支——要么返回getGroupInfo(id)的Promise实例,要么返回getUserInfo(id.split('@')[0], app.currentUserDomain)的Promise实例。这两个函数从代码结构来看,应该都是返回Promise的异步函数,所以getRemoteProfile最终会返回一个处于pending状态的Promise,直到内部的异步操作完成。
接下来看reloadProfile里的then回调,会出现三种情况:
- 如果
getGroupInfo或getUserInfo的Promise最终resolve了一个非null的值:then回调里的contactProfile就是这个值,会进入if (contactProfile)分支,执行设置contact_id、删除缓存(若keep为false)、标记member、更新头像等逻辑,最后返回setDetails(contactProfile)的结果(这个应该也是Promise,所以整个reloadProfile返回的Promise会跟随它的状态)。 - 如果这两个Promiseresolve了null:
if (contactProfile)条件不成立,then回调不会执行任何逻辑,最终返回undefined,所以reloadProfile返回的Promise会resolve为undefined。 - 如果这两个Promise被rejected(比如请求失败):因为
reloadProfile里没有给getRemoteProfile().then(...)添加catch回调,这个rejection会直接冒泡出去,需要调用reloadProfile的代码通过.catch()来处理这个错误。
问题2:return promise与return Promise.resolve(...)的区别
先纠正你一个小误解:return Promise.resolve(...)并不总是会进入then回调,得看它包裹的值是什么。下面详细对比两者:
1. return promise
这里的promise是一个已经存在的Promise实例。直接返回它的话,后续的链式调用会完全继承这个Promise的状态:
- 如果原Promise是resolved状态:后续的
then回调会触发,接收原Promise的resolve值。 - 如果原Promise是rejected状态:后续的
catch回调(如果有的话)会触发,接收原Promise的reject原因。 - 如果原Promise是pending状态:后续的回调会等待它的状态变更后再执行。
比如你的代码里return getGroupInfo(id),就是直接返回这个函数创建的Promise,后续逻辑完全依赖这个Promise的执行结果。
2. return Promise.resolve(x)
这是创建一个新的Promise实例,并且尝试将其resolve为x:
- 如果
x是普通值(非Promise):这个新Promise会立即进入resolved状态,后续的then回调会触发,接收x作为参数。 - 如果
x是一个Promise实例:Promise.resolve(x)会“接管”这个Promise的状态——等待x的状态变更,然后新Promise的状态会和x完全一致。也就是说,如果x最终是rejected的,那么Promise.resolve(x)也会变成rejected状态,这时候后续的catch回调会触发,而不是then。 - 如果
x是thenable对象(带有then方法的对象):Promise.resolve(x)会调用这个then方法,并且跟随它的状态变更。
举个简单的例子:
// 情况1:x是普通值,进入then return Promise.resolve('hello') // 情况2:x是rejected的Promise,进入catch return Promise.resolve(Promise.reject('request failed'))
内容的提问来源于stack exchange,提问作者Rasim Avcı
相关产品推荐
相关产品推荐

