JavaScript如何在关联Promise的setTimeout内定义可正常访问的全局变量
问题核心原因
- 执行时序问题:同步代码优先于所有异步代码执行,你写在最外层的
console.log(c)属于同步任务,执行时setTimeout的2秒延时还没触发,回调函数未运行,变量c还没被赋值,所以输出undefined。 - 赋值逻辑错误:
c = k.then(...)中,then()方法返回的是新的Promise实例,你实际是把这个Promise实例赋值给了c,并非你想要的resolve结果you are okay。
解决方案
方案1:用async/await处理(可读性更高)
如果没有强制要求使用全局变量,更推荐这种写法,避免全局变量污染:
const k = new Promise((resolve, reject) => { 2 < 4 ? resolve('you are okay') : reject('You are not okay'); }); async function test() { // 等待2秒,替代原setTimeout逻辑 await new Promise(resolve => setTimeout(resolve, 2000)); // 等待Promise执行完成拿到返回值 const c = await k; console.log(c, "x in then"); console.log(c, "in setTimeout"); // 所有需要用到c的后续逻辑都写在这里即可 console.log(c, "c的正常输出"); } test();
如果必须使用全局变量c,只需把c的声明提到全局,在await拿到结果后赋值即可,注意所有依赖c的逻辑仍要保证在异步流程结束后执行。
方案2:用Promise链式调用处理
const k = new Promise((resolve, reject) => { 2 < 4 ? resolve('you are okay') : reject('You are not okay'); }); var c; function test() { setTimeout(() => { k.then(x => { // 把Promise返回的结果赋值给c c = x; console.log(x, "x in then"); console.log(c, "in setTimeout"); // 所有需要用到c的逻辑都放在这个回调内部执行 console.log(c, "c的正常输出"); }) }, 2000); } test();
核心注意点:所有依赖c取值的逻辑,绝对不能写在全局同步执行的位置,必须放到异步回调内部,保证执行时c已经完成赋值。
内容的提问来源于stack exchange,提问作者rsc05
相关产品推荐
相关产品推荐

