JavaScript中如何让代码在XMLHttpRequest的onreadystatechange回调后执行
问题原因
XMLHttpRequest 默认是异步执行的,request.send() 调用后不会等待请求返回就会直接向下执行末尾的三行代码,这时候 onreadystatechange 回调还没触发,objFromJson 还是初始的空字符串,自然拿不到 page.next 的值。
方案1:直接将逻辑移入回调(改动最小)
把需要等请求完成的逻辑直接放到 onreadystatechange 的请求成功分支末尾即可:
const tournamentsList = document.getElementById('tournaments-name-list'); const request = new XMLHttpRequest(); request.open( "GET", "https://cricheroes.in/api/v1/tournament/get-tournaments/-1?pagesize=12&status=-1" ); let objFromJson = ""; request.onreadystatechange = () => { if (request.readyState === 4 && request.status === 200) { objFromJson = JSON.parse(request.response) console.log(objFromJson) for (let i = 0; i < objFromJson.data.length; i++) { tournamentsList.innerHTML += ` <li class="tournaments-name">${objFromJson.data[i].name}</li>`; } // url 逻辑移到回调内部 let url = ""; url = objFromJson.page.next; console.log(url); } }; request.send();
方案2:Promise 封装 XHR(适合扩展场景)
如果后续还有其他逻辑需要依赖请求结果,推荐用 Promise 封装 XHR,配合 async/await 写出来的逻辑更清晰,避免回调嵌套:
// 封装请求为 Promise function fetchTournaments() { return new Promise((resolve, reject) => { const request = new XMLHttpRequest(); request.open( "GET", "https://cricheroes.in/api/v1/tournament/get-tournaments/-1?pagesize=12&status=-1" ); request.onreadystatechange = () => { if (request.readyState === 4) { request.status === 200 ? resolve(JSON.parse(request.response)) : reject(new Error('请求失败')) } }; request.send(); }) } // 按顺序执行逻辑 async function init() { const tournamentsList = document.getElementById('tournaments-name-list'); const objFromJson = await fetchTournaments(); console.log(objFromJson) for (let i = 0; i < objFromJson.data.length; i++) { tournamentsList.innerHTML += ` <li class="tournaments-name">${objFromJson.data[i].name}</li>`; } // 后续逻辑直接按顺序写即可 let url = ""; url = objFromJson.page.next; console.log(url); } init();
内容的提问来源于stack exchange,提问作者Muhammad Bilal
相关产品推荐
相关产品推荐

