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

如何并行发起多链接GET请求并按序判断结果以终止后续请求

如何实现按请求返回顺序判断并终止剩余请求

需求与问题梳理

需求:同时发起多个GET请求,按请求结果返回的顺序逐个判断——第一个返回的结果符合条件则终止所有剩余请求;若不符合,继续判断下一个返回的结果,以此类推,直到找到符合条件的或所有请求完成。

原代码存在的问题:

  • 仅通过Promise.race获取第一个完成的请求,判断不符合后使用Promise.all等待所有请求完成再遍历,并非按返回顺序逐个判断
  • 原Promise未封装取消能力,无法真正中止未完成的GM_xmlhttpRequest请求
  • 逻辑错误:第一个结果不符合时,没有继续按返回顺序处理后续完成的请求,而是等待全部完成后统一处理,不符合需求

解决方案

核心思路:同时发起所有请求,为每个请求封装取消能力,监听每个请求的完成事件,按返回顺序依次检查结果,一旦找到符合条件的,立即中止所有未完成的请求并停止后续判断。

实现代码

// 封装带取消能力的请求函数
function createRequestPromise(url) {
    let xhr;
    const promise = new Promise((resolve) => {
        xhr = GM_xmlhttpRequest({
            method: "GET",
            url: url,
            onload: function(response) {
                try {
                    const domNew = new DOMParser().parseFromString(response.responseText, 'text/html');
                    resolve({ data: domNew, url });
                } catch (e) {
                    resolve({ data: 'ERROR_PARSE', url });
                }
            },
            onerror: function(error) {
                resolve({ data: 'ERROR_REQUEST', url });
            }
        });
    });
    // 添加cancel方法,用于中止请求
    promise.cancel = () => {
        if (xhr && typeof xhr.abort === 'function') {
            xhr.abort();
        }
    };
    return promise;
}

// 请求链接列表
const urls = [
    'https://www.aaa.com',
    'https://www.bbb.com',
    'https://www.ccc.com'
];

// 生成所有请求Promise
const requestPromises = urls.map(url => createRequestPromise(url));
let found = false; // 标记是否已找到符合条件的结果

// 监听每个请求的完成
requestPromises.forEach(promise => {
    promise.then(result => {
        if (found) return; // 已找到符合条件的,直接返回

        const { data, url } = result;
        // 条件判断:区分错误结果与DOM对象的检查逻辑
        const meetsCondition = typeof data === 'string' 
            ? data.indexOf('#') > -1 
            : data.querySelector('#') !== null;

        if (meetsCondition) {
            found = true;
            console.log(`找到符合条件的结果,来自链接:${url}`, data);
            // 中止所有未完成的请求
            requestPromises.forEach(p => p.cancel());
        } else {
            console.log(`链接${url}不符合条件,继续等待...`);
            // 检查是否所有请求均已完成且未找到符合条件的
            Promise.allSettled(requestPromises).then(results => {
                if (!found && results.every(r => r.status === 'fulfilled')) {
                    console.log('所有请求均已完成,未找到符合条件的结果');
                }
            });
        }
    });
});

关键细节说明

  • 请求封装:createRequestPromise函数保存了GM_xmlhttpRequest的实例,并给Promise添加cancel方法,调用时执行xhr.abort()真正中止请求
  • 顺序判断:每个请求完成后触发then回调,通过found标志位避免重复处理,严格按返回顺序检查条件
  • 中止逻辑:一旦找到符合条件的结果,立即调用所有未完成请求的cancel方法,停止后续请求的处理
  • 条件判断修正:原代码直接对DOM对象调用indexOf('#')会报错,这里区分了字符串错误结果与DOM对象的检查逻辑,确保判断有效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 11:17:04