You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何提前执行HTTP请求并在鼠标交互时处理结果?能否无延迟判断请求完成?

如何判断预加载的HTTP请求是否完成后再执行打开链接操作

需求回顾

提前发起HTTP请求获取目标链接,当鼠标移动到页面指定元素上时,仅在请求完成后打开返回的最终链接,避免使用固定延迟(如1500ms)等待请求。

原代码的问题

原代码通过全局变量jhref存储链接,但没有明确标记请求的完成状态,鼠标hover时无法确定jhref是否已经是请求后的最终链接,容易出现打开初始链接(http://aaa.com)的情况。


解决方案1:用状态变量跟踪请求状态

新增一个状态变量标记请求的进展,鼠标hover时先判断状态,再执行对应操作:

// 全局变量:存储最终链接和请求状态
let jhref = 'http://aaa.com';
let requestStatus = 'pending'; // 可选值: pending(进行中)/success(成功)/error(失败)

function getWebsite(s) {
    GM_xmlhttpRequest({
        method: 'GET',
        url: jhref,
        onload: function (result) {
            let domNew = new DOMParser().parseFromString(result.responseText, 'text/html');
            let linkElement = domNew.querySelectorAll('.item>a')[0];
            if (linkElement) {
                jhref = linkElement.href;
                requestStatus = 'success';
            } else {
                requestStatus = 'error';
                console.log('未找到目标链接');
            }
        },
        onerror: function (result) {
            requestStatus = 'error';
            console.log('请求失败:', result);
        },
        onabort: function() {
            requestStatus = 'error';
            console.log('请求被中止');
        }
    });
}

// 立即发起预加载请求
getWebsite(text);

// 给目标元素绑定鼠标移入事件(替换成你的元素选择器)
document.querySelector('.target-element').addEventListener('mouseover', function() {
    switch(requestStatus) {
        case 'success':
            window.open(jhref);
            break;
        case 'pending':
            console.log('请求还在处理中,请稍候');
            // 可选:如果想等请求完成再打开,可以加个轮询
            // const checkStatus = setInterval(() => {
            //     if(requestStatus === 'success') {
            //         window.open(jhref);
            //         clearInterval(checkStatus);
            //     }
            // }, 100);
            break;
        case 'error':
            console.log('请求失败,无法打开链接');
            break;
    }
});

解决方案2:用Promise封装请求(更优雅)

将请求封装为Promise,利用Promise的状态自动跟踪请求进展,鼠标hover时直接等待请求完成:

// 把请求封装成Promise
function getWebsite(s) {
    const initialUrl = 'http://aaa.com';
    return new Promise((resolve, reject) => {
        GM_xmlhttpRequest({
            method: 'GET',
            url: initialUrl,
            onload: function (result) {
                let domNew = new DOMParser().parseFromString(result.responseText, 'text/html');
                let linkElement = domNew.querySelectorAll('.item>a')[0];
                if (linkElement) {
                    resolve(linkElement.href); // 请求成功,返回最终链接
                } else {
                    reject(new Error('未找到目标链接'));
                }
            },
            onerror: function (result) {
                reject(new Error('请求失败: ' + result.statusText));
            },
            onabort: function() {
                reject(new Error('请求被中止'));
            }
        });
    });
}

// 立即发起预加载请求,得到Promise实例
const linkPromise = getWebsite(text);

// 给目标元素绑定鼠标移入事件(替换成你的元素选择器)
document.querySelector('.target-element').addEventListener('mouseover', async function() {
    try {
        // 等待请求完成(如果已经完成会直接返回结果)
        const finalLink = await linkPromise;
        window.open(finalLink);
    } catch (err) {
        console.log('无法打开链接:', err.message);
    }
});

方案对比

  • 方案1适合简单场景,状态变量直观易懂,适合快速改造原有代码
  • 方案2符合现代JS异步编程习惯,处理异步逻辑更优雅,无需手动维护状态,还能自然等待请求完成

内容的提问来源于stack exchange,提问作者lyscop

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 17:31:04