递归调用Promise时为何必须调用resolve()方法
问题解答
你的理解完全正确。
Promise 基础状态规则
JavaScript 中 Promise 实例有且仅有三种互斥状态:
pending:初始等待状态,此时绑定的then/catch/finally回调都不会执行fulfilled:已兑现状态,通过调用resolve()触发,会执行对应的then成功回调rejected:已拒绝状态,通过调用reject()触发,会执行对应的catch/then失败回调
状态一旦从pending变更为另外两种之一,就会永久凝固,不会再改变。
你的递归代码执行逻辑
你写的分页递归拉取逻辑,本质是层层依赖的Promise链:
- 最外层首次调用
fetchRuns会返回一个全新的Promise实例,你绑定的() => console.log("abc")就是挂在这个最外层Promise的then回调上,只有这个最外层Promise变成fulfilled状态,回调才会执行 - 当单次请求返回后如果还有下一页,你写的
resolve(this.fetchRuns(下一页url))属于Promise解包逻辑:当前层的Promise会等待内层递归调用返回的Promise状态变更,内层Promise不resolve,当前层就会一直停在pending - 只有触发递归终止条件(累计拉取满100条、没有下一页链接)时,最内层的Promise会先调用
resolve()进入fulfilled状态,之后逐层向外触发所有等待的外层Promise依次resolve,直到最外层Promise状态变更,最终才会执行打印abc的逻辑
如果任意一层递归漏写了
resolve()或者reject(),该层Promise会永久停在pending状态,外层所有依赖它的Promise也会一直挂起,整条Promise链在这里断裂,后续绑定的所有回调永远不会触发。
额外提一句你现有代码的小问题:当前fetch请求链没有加错误捕获,一旦网络报错、JSON解析失败、接口返回结构异常,对应层的Promise也会永久挂起,建议在fetch链末尾加.catch(err => reject(err)),避免出现无响应的静默错误。
内容的提问来源于stack exchange,提问作者DasEvoli
相关产品推荐
相关产品推荐

