likes
comments
collection
share

异步操作,让你的 JavaScript 更加优雅和高效!

作者站长头像
站长
· 阅读数 3

深入探究:手动编写 Ajax 请求与异步操作

在现代 Web 开发中,Ajax 技术扮演着至关重要的角色,它让我们能够在不刷新整个页面的情况下,通过异步方式获取数据并对页面进行局部刷新。今天,我们将一起深入探究 Ajax 技术,并通过手写代码的方式来理解其工作原理。

首先,让我们从头开始,逐行分析一个手动编写 Ajax 请求的示例代码,并详细解释其中的注释。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Ajax</title>
</head>
<body>
<script>
// 定义一个函数 fetchJSONData,用于发送 Ajax 请求并获取数据
const fetchJSONData = function(url) {
    // 返回一个 Promise 对象,用于处理异步操作
    return new Promise((resolve, reject) => {
        // 创建 XMLHttpRequest 对象,用于发送 HTTP 请求
        const xhr = 
            XMLHttpRequest
            ? new XMLHttpRequest()
            : new ActiveXObject('Microsoft.XMLHTTP');
        // 初始化 HTTP 请求
        xhr.open('GET', url, false);
        // 监听 XMLHttpRequest 对象的状态变化
        xhr.onreadystatechange = function() {
            // 当请求完成时执行以下操作
            if (xhr.readyState !== 4) return;
            // 根据 HTTP 状态码判断请求结果
            if (xhr.status === 200 || xhr.status === 304) {
                // 如果请求成功,则调用 resolve 方法并传入响应数据
                resolve(xhr.responseText);
            } else {
                // 如果请求失败,则调用 reject 方法并传入错误信息
                reject(new Error(xhr.responseText));
            }
        };
        // 发送 HTTP 请求
        xhr.send();
    });
};

// 使用 async/await 语法糖来处理异步操作
(async function() {
    // 调用 fetchJSONData 函数发送 Ajax 请求
    const p = fetchJSONData('https://api.github.com/users/shunwuyu/repos');
    console.log('....');
    console.log(p); // 输出 Promise 对象的状态和值
    // 等待 Promise 对象的状态变为 resolved,并获取返回的数据
    const res = await p;
    console.log(p, res); // 输出 Promise 对象和返回的数据
})();
</script>
</body>
</html>

让我们一行一行地解释这段代码:

  1. 首先,我们定义了一个名为 fetchJSONData 的函数,用于发送 Ajax 请求并获取数据。
  2. 然后,在函数内部,我们返回一个 Promise 对象,以便处理异步操作。Promise 是 JavaScript 中用于处理异步操作的一种机制。
  3. 在 Promise 的构造函数中,我们创建了一个 XMLHttpRequest 对象(XMLHttpRequest 是一个内建对象,用于发送 HTTP 请求)。
  4. 接下来,我们调用 open 方法来初始化 HTTP 请求,使用 GET 方法和指定的 URL。
  5. 我们使用 onreadystatechange 事件监听 XMLHttpRequest 对象的状态变化。当 readyState 不等于 4(请求完成)时,我们不执行任何操作。
  6. 当请求完成时,我们检查 HTTP 状态码(xhr.status)。如果状态码是 200 或者 304,表示请求成功。
  7. 如果请求成功,我们调用 resolve 方法并传入响应数据,将 Promise 对象的状态标记为 resolved。
  8. 如果请求失败,我们调用 reject 方法并传入错误信息,将 Promise 对象的状态标记为 rejected。
  9. 最后,我们调用 send 方法发送 HTTP 请求。
  10. 在主程序中,我们使用 async/await 语法糖来处理异步操作。通过将代码包装在一个自执行的 async 函数中,我们可以使用 await 来等待 Promise 对象的状态变为 resolved,并获取返回的数据。
  11. 我们调用 fetchJSONData 函数发送 Ajax 请求,并将返回的 Promise 对象存储在变量 p 中。
  12. 接着,我们在控制台打印一些信息,包括 Promise 对象的状态和值。
  13. 最后,我们使用 await 等待 Promise 对象的状态变为 resolved,并将返回的数据存储在变量 res 中。然后,我们再次在控制台打印 Promise 对象和返回的数据。

注意下面两个小细节(可能就是进大厂的契机哦)

兼容性问题

// 兼容性 IE6.0以前 现在没什么必要 IE过去式了
        const xhr = 
            XMLHttpRequest
            ? new XMLHttpRequest()
            : new ActiveXObject('Microsoft.XMLHTTP')

在现代浏览器中,基本上不再需要考虑这些兼容性问题,因为现代浏览器都支持标准的XMLHttpRequest对象,无需使用ActiveXObject来创建XMLHTTP对象。

对于现代浏览器,我们可以简单地使用以下代码来创建XMLHttpRequest对象:

const xhr = new XMLHttpRequest();

这样就可以满足现代浏览器的需求了。然而,如果你的应用需要支持旧版的IE浏览器,那么你可能需要考虑使用类似于你提到的兼容性写法,但需要注意的是,对于安全性和性能考量,尽量避免支持过于陈旧的浏览器。但是对于要进大厂的各位来说,这还是需要了解一下的。

xhr.status === 304

xhr.status的值为304时,表示请求的资源在客户端的缓存中仍然是有效的,服务器告知客户端可以直接使用缓存的数据,不需要重新获取。这是一种优化机制,被称为HTTP缓存。

在这种情况下,通常可以省略对响应数据的处理,直接使用之前缓存的数据即可。这有助于提高页面加载速度和减少网络流量。

请注意,304状态码只能在使用了适当的缓存策略(例如设置了合适的Cache-Control头部)的情况下才会返回,并且浏览器会自动处理这种情况。因此,在JavaScript代码中手动检查xhr.status是否为304通常并不是必要的。

总之,当xhr.status的值为304时,可以认为请求成功,并且可以直接使用缓存的数据。这可能也是大厂的考点之一哦!!!

通过这段代码,我们可以深入理解以下几个重要点:

  1. XMLHttpRequest 对象的创建和使用:通过创建 XMLHttpRequest 对象,我们能够发送 HTTP 请求并监听其状态变化,从而实现异步获取数据的功能。

  2. Promise 的使用:通过返回 Promise 对象,我们可以更好地处理异步操作,将成功和失败的情况分别交给 resolve 和 reject 处理。

  3. async/await 语法糖的应用:通过 async/await 语法糖,我们可以更加优雅地处理异步操作,避免回调地狱的问题,提高代码的可读性和可维护性。


希望这篇文章能给大家带来帮助!