Promise已完成时加载指示器仍保持激活状态的原因探究
下面是几种最可能出现的情况:
没把停止逻辑放进
finally()里
要是你只在then()(成功分支)或者catch()(失败分支)里写了停止指示器的代码,一旦Promise走了没被覆盖的分支(比如只写了then()但Promise reject了),停止逻辑就不会执行,指示器自然一直亮着。正确的做法是:不管成功失败都要执行的清理逻辑,必须丢进finally()。finally()里的代码报错了
如果finally里的停止逻辑本身出了问题——比如调用了不存在的方法、要操作的DOM元素已经被移除,代码会直接抛出错误中断执行,指示器的停止步骤根本走不完。比如你写了loading.hide()但实际方法名是loading.hideIndicator(),这就会直接报错,导致停不下来。Promise其实没真正完成
别被“以为完成了”误导——如果Promise一直卡在pending状态(比如请求没收到响应也没加超时处理、异步逻辑死循环了),finally()根本不会触发,指示器当然会一直保持激活。这种情况得先确认你的Promise到底有没有进入fulfilled或者rejected状态。作用域问题搞混了指示器实例
要是在异步逻辑里不小心重定义了同名的指示器变量,或者用了全局变量被其他代码修改,导致finally()里调用的停止方法对应的不是你一开始启动的那个指示器实例,那自然停不下来。比如你启动了const loader = new LoadingIndicator(),但后面异步代码里又写了let loader = null,那finally里的loader.stop()就等于调用null的方法,根本没用。
内容的提问来源于stack exchange,提问作者The Real Bogdan

