如何在不修改现有loadDoc123代码的情况下实现Promise JS?
如何在不修改原代码的情况下用Promise封装
loadDoc123函数? 没问题!我们可以写一个包装函数,把现有的loadDoc123包裹起来,让它的异步请求逻辑支持Promise,完全不用改动原函数的一行代码。
实现思路
原函数loadDoc123内部创建了一个XMLHttpRequest实例并绑定了回调,但这个实例是局部变量,我们没法直接访问。所以我们可以临时拦截XMLHttpRequest的构造过程,给创建的实例绑定Promise的resolve/reject逻辑,等请求完成后再恢复原构造函数,避免影响其他代码。
完整代码示例
首先保留你的原函数不动:
function loadDoc123() { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { document.getElementById("demo").innerHTML = this.responseText; } }; xhttp.open("GET","demo_get2.asp?fname=Henry&lname=Ford", true); xhttp.send(); }
然后添加这个包装函数:
function loadDoc123WithPromise() { return new Promise((resolve, reject) => { // 保存原生XMLHttpRequest构造函数 const OriginalXHR = XMLHttpRequest; // 临时替换构造函数,拦截新创建的XHR实例 XMLHttpRequest = function() { const xhr = new OriginalXHR(); // 给XHR实例绑定我们的状态监听 xhr.onreadystatechange = function() { if (this.readyState === 4) { // 请求完成后还原原生构造函数 XMLHttpRequest = OriginalXHR; if (this.status === 200) { resolve(this.responseText); // 请求成功时resolve } else { reject(new Error(`请求失败,状态码:${this.status}`)); // 请求失败时reject } } }; return xhr; }; // 调用原函数,它会使用我们替换后的构造函数创建XHR loadDoc123(); }); }
如何使用
现在你可以用Promise的链式调用或者async/await来处理这个异步操作了:
链式调用方式
loadDoc123WithPromise() .then(responseText => { console.log("请求成功!响应内容:", responseText); // 原函数已经自动把内容插入到#demo元素里了,这里可以做额外的后续操作 }) .catch(error => { console.error("请求出错:", error.message); });
async/await方式
async function fetchData() { try { const responseText = await loadDoc123WithPromise(); console.log("请求成功!响应内容:", responseText); } catch (error) { console.error("请求出错:", error.message); } } // 调用函数 fetchData();
注意事项
- 这个方法适合单独调用
loadDoc123的场景,如果同时有多个XHR请求在进行,临时替换构造函数可能会影响其他请求,建议在确保没有并发请求的情况下使用。 - 原函数的DOM操作逻辑会被完整保留,Promise只是额外给你提供了异步操作的状态回调能力。
内容的提问来源于stack exchange,提问作者baroad
相关产品推荐
相关产品推荐

