使用 ajaxSetup dataFilter 的并行请求

Posted

技术标签:

【中文标题】使用 ajaxSetup dataFilter 的并行请求【英文标题】:Parallel requests with ajaxSetup dataFilter 【发布时间】:2022-01-03 13:05:26 【问题描述】:

我必须连接到现有的 ajax 请求(我无法更改,它在我们的 CMS 中)并添加一些额外的数据。更具体地说,它是一个加载图像数据 (json) 的媒体库,我正在从外部源添加更多图像。

var promise_waiting = [];

jQuery.ajaxSetup(
    beforeSend: function() 

        // starting external library request, so they can run in parallel
        promise_waiting = new Promise( function(resolve, reject) 
            jQuery.get(external_library_url, , function(data) 
                if(data) 
                    console.log('external library request done');
                    resolve(data);
                
            );
        );

        return true;
    ,
    dataFilter: async function (data) 
        console.log('original request done');

        // waiting for that external library request to resolve
        ext_data = await promise_waiting;

        console.log('both requests done');
        return data.concat(ext_data);
    
)

这两个请求都按照我希望的方式完成,所以一切正常。问题是dataFilter 不能是异步函数,没有错误或警告,但是在请求(渲染图像预览)之后执行的代码永远不会触发。

我目前唯一的选择是在 dataFilter 中使用非异步 ajax 请求,这不是最优的,因为两个请求单独需要相当长的时间。

我正在寻找此设置的替代方案,在此先感谢您

【问题讨论】:

【参考方案1】:

由于无法更改 $.ajax() 调用并且 beforeSenddataFilter 不允许异步,您需要手动执行异步 beforeSend,我认为您无法避免“劫持”jQuery.fn.ajax

可能是这样的:-

function myBeforeSend(data) 
    return $.get(external_library_url, )
    .then(ext_data => data.concat(ext_data || []));


(function($, beforeSend)  // i.i.f.e.
    // make an alias for $.fn.ajax
    let $.fn.originalAjax = $.fn.ajax;

    // now hijack $.fn.ajax (in a good way)
    $.fn.ajax = function(...args) 
        // allow for $.ajax's flexible args .... $.ajax(url, [settings]) or $.ajax([settings])
        let settings = Object.assign(, args[1] || );
        if (typeof args[0] === "string") 
            settings.url = args[0]; // standardise settings to include url.
        
        return beforeSend(settings.data || [])
        .then(filteredData => $.originalAjax(Object.assign(settings,  'data':filteredData )));
    ;
)(jQuery, myBeforeSend);

args 的组成相当安全,但请务必彻底测试。

【讨论】:

我看到你在这里尝试做什么,但我需要原始 ajax 请求的结果与我的 ext_data 合并。不幸的是,劫持 ajax 确实破坏了其他一些东西 @devssc, "需要原始 ajax 请求的结果才能与我的 ext_data 合并" ...除非我犯了错误,这正是它应该的行为方式. beforeSend() 发出初始请求并返回一个传递合并数据的 Promise,该数据依次传递给第二个 ajax 请求。 哎呀,一个小错误,args[2] 应该是 args[1](已编辑)。 其他东西破坏的问题可能是由于 settings.data || [] 表达式,默认为空数组。也许默认为空的普通对象 会更好,尽管这需要 beforeSend() 区分数组和普通对象。

以上是关于使用 ajaxSetup dataFilter 的并行请求的主要内容,如果未能解决你的问题,请参考以下文章

kendo UI使用基础介绍与问题整理——Grid问题/demo参数datafilter等

jQuery.ajaxSetup()

$.ajaxSetup 中的 beforeSend + $.ajax 中的 beforeSend

jquery中的ajaxSetup

jQuery.ajaxSetup()

JavaScript 学习-48.$.ajaxSetup方法设置AJAX的全局默认设置