如何编写Promise等待JavaScript中变量的值发生变化?
解决方案
你之前的写法无效的原因很明确:
- 第一个Promise创建后立即调用
resolve(AJAXvariable),此时变量还没被AJAX请求赋值,直接返回了初始的undefined或空值,后续变量变化不会影响已resolve的Promise。 - 第二个写法里
await的不是Promise对象,AJAXvariable !== ""是普通布尔表达式,await会直接返回它的结果,根本不会等待变量变化。
要实现“等变量值变化后再resolve Promise”,有两种可行思路:
思路1:直接把AJAX请求包装成Promise(推荐)
这是最合理的方式,变量变化本质是AJAX请求完成的结果,没必要绕弯监听变量,直接在请求回调里控制Promise状态。
原生AJAX的Promise封装示例:
function fetchDBData() { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open('GET', '你的数据库接口地址'); xhr.onload = function() { if (xhr.status >= 200 && xhr.status < 300) { const AJAXvariable = JSON.parse(xhr.responseText); resolve(AJAXvariable); } else { reject(new Error('请求失败')); } }; xhr.onerror = function() { reject(new Error('网络错误')); }; xhr.send(); }); } // 使用方式 async function useData() { try { const data = await fetchDBData(); // 这里直接使用获取到的数据库数据 console.log(data); } catch (err) { console.error('获取数据失败:', err); } } useData();
如果用jQuery的$.ajax,代码可以更简洁:
function fetchDBData() { return $.ajax({ url: '你的数据库接口地址', type: 'GET' }); } // 使用方式和上面一致 async function useData() { try { const data = await fetchDBData(); console.log(data); } catch (err) { console.error(err); } }
思路2:监听变量的变化(仅当无法修改AJAX请求代码时使用)
如果受限于现有代码,不能修改AJAX请求逻辑,必须通过监听变量变化触发Promise,可以用Object.defineProperty给变量设置setter,拦截赋值操作并resolve Promise。
示例代码:
// 初始化变量 let AJAXvariable = ""; // 存储Promise的resolve函数 let resolveFn; // 创建等待变量变化的Promise const waitForData = new Promise((resolve) => { resolveFn = resolve; }); // 给变量设置setter,赋值时触发resolve Object.defineProperty(window, 'AJAXvariable', { set: function(newValue) { AJAXvariable = newValue; // 变量变为有效数据时resolve if (newValue !== "" && newValue !== undefined) { resolveFn(newValue); } }, get: function() { return AJAXvariable; } }); // 模拟原有AJAX请求(假设无法修改这段代码) setTimeout(() => { AJAXvariable = { id: 1, name: "测试数据" }; }, 30); // 使用方式 async function useData() { const data = await waitForData; console.log('拿到数据:', data); } useData();
注意:如果变量可能被多次赋值,可添加标记位避免重复resolve。
内容的提问来源于stack exchange,提问作者Mark Lamprey
相关产品推荐
相关产品推荐

