【问题标题】:Parallel requests with ajaxSetup dataFilter使用 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 请求,这不是最优的,因为两个请求单独需要相当长的时间。

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

【问题讨论】:

    标签: javascript jquery ajax async-await promise


    【解决方案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() 区分数组和普通对象。
    猜你喜欢
    • 2017-06-27
    • 2012-04-23
    • 2018-09-17
    • 1970-01-01
    • 1970-01-01
    • 2018-06-08
    • 2011-10-23
    • 1970-01-01
    相关资源
    最近更新 更多