Jquery Ajax 防止在延迟顺序循环中失败

IT技术 javascript jquery ajax
2021-03-02 21:54:50

因此,我将顺序 ajax 链接在一起,以按顺序加载一组 url。最初我使用.then()而不是.always(), 并且无论哪种方式都可以正常工作 - 前提是所有网址都存在。但是,由于存在丢失文件的可能性,我想对此进行补偿,然后最后通知用户丢失了哪些文件,以便更容易纠正。

然而,问题是,在丢失的文件/404 上,代码会像它应该的那样执行,但随后退出循环,阻止任何进一步的 ajax 调用。所以我想,我需要某种方式来处理fail()并强制成功,或者某种其他方式来覆盖 404 上的默认行为,因此它会继续在循环中进行。

不幸的是,最接近的谷歌结果是如何做相反的事情(强制失败成功)。

var missing=[];
uLoadList.reduce(function(prev, cur, index) {
    return prev.then(function(data) {
        return $.ajax("/wiki/"+cur).always(function(data) {
            var temp = $('#mw-content-text',data);
            temp = $('pre',temp);
            if(temp.length > 0)
            {
                //handle success
            }else{
                //handle failure
                missing.push(cur);
            }
        });
    });
}, $().promise()).done(function() {
    if(missing.length > 0)
    {
        //notify of missing objects
    }
    //continue on.
});

最后一点,为了减轻混淆:URL 和脚本本身都在 MediaWiki 站点上 - 因此即使返回 404,也总会有页面内容,并且将包含 id 为“mw-content”的元素-文本”。

1个回答

尝试

(function ($) {
    $.when.all = whenAll;
    function whenAll(arr) {
        "use strict";
        var deferred = new $.Deferred(),
            args = !! arr 
                   ? $.isArray(arr) 
                     ? arr 
                     : Array.prototype.slice.call(arguments)
                       .map(function (p) {
                         return p.hasOwnProperty("promise") 
                         ? p 
                         : new $.Deferred()
                           .resolve(p, null, deferred.promise())
                       }) 
                   : [deferred.resolve(deferred.promise())],
            promises = {
                "success": [],
                  "error": []
            }, doneCallback = function (res) {
                promises[this.state() === "resolved" 
                         || res.textStatus === "success" 
                         ? "success" 
                         : "error"].push(res);
                return (promises.success.length 
                       + promises.error.length) === args.length 
                       ? deferred.resolve(promises) 
                       : res
            }, failCallback = function (res) {
                // do `error` notification , processing stuff
                // console.log(res.textStatus);
                promises[this.state() === "rejected" 
                        || res.textStatus === "error" 
                        ? "error" 
                        : "success"].push(res);
                return (promises.success.length 
                       + promises.error.length) === args.length 
                       ? deferred.resolve(promises) 
                       : res
            };
        $.map(args, function (promise, index) {
            return $.when(promise).always(function (data, textStatus, jqxhr) {
                return (textStatus === "success") 
                    ? doneCallback.call(jqxhr, {
                        data: data,
                        textStatus: textStatus 
                                    ? textStatus 
                                    : jqxhr.state() === "resolved" 
                                      ? "success" 
                                      : "error",
                        jqxhr: jqxhr
                      }) 
                    : failCallback.call(data, {
                        data: data,
                        textStatus: textStatus,
                        jqxhr: jqxhr
                      })
            })
        });
        return deferred.promise()
    };
}(jQuery));
// returns `Object {
//                   success: Array[/* success responses*/], 
//                   error: Array[/* error responses */]
//          }`

// e.g.,
var request = function (url, data) {
    return $.post(url, {
        json: JSON.stringify(data)
    })
}, settings = [
    ["/echo/json/", "success1"], // `success`
    ["/echo/jsons/", "error1"], // `error`
    ["/echo/json/", "success2"], // `success`
    ["/echo/jsons/", "error2"], // `error`
    ["/echo/json/", "success3"] // `success`
];

$.when.all(
  $.map(settings, function (p) {
    return request.apply($, p)
  })
)
.then(function (data) {
    console.log(data);
    // filter , process responses
    $.each(data, function(key, value) {
        if (key === "success") {
          results.append(
              "\r\n" + key + ":\r\n" + JSON.stringify(value, null, 4)
          )
        } else {            
          results.append(
              "\r\n" + key + ":\r\n" 
              + JSON.stringify(
                  value.map(function(v, k) {
                    v.data.responseText = $(v.data.responseText)
                      .filter("title, #summary, #explanation")
                      .text().replace(/\s+/g, " ");
                    return v
                  })
                , null, 4)
          )
        }
    })
}, function (e) {
    console.log("error", e)
});

jsfiddle http://jsfiddle.net/guest271314/620p8q8h/

@Roamer-1888 不确定“更传统”的含义?或“更具可读性”两者都可以基于感知、预先确定的偏好;还是主观的?如果js使用上述三元模式组合会导致js出现“更传统”或“更具可读性”,是的,请使用该特定模式组合。fwiw,这里没有注意到实质性差异,建议使用三元模式“更具可读性”;js从头开始组成,没有“惯例”。任一模式似乎返回相同的结果jsfiddle.net/guest271314/620p8q8h/5
2021-04-21 21:54:50
无论哪种方式,这都不是什么大问题。正如您所说,两个版本都给出了相同的结果。
2021-05-02 21:54:50
当然是的,但应用我的重新排列,你最终会得到一个更传统、更易读的版本, args = !arr ? [deferred.resolve(deferred.promise())] : $.isArray(arr) ? arr : Array.prototype.slice.call(arguments).map(function (p) { return p.hasOwnProperty('promise') ? p : new $.Deferred().resolve(p, null, deferred.promise()); });
2021-05-04 21:54:50
嵌套的三元组!!a ? b ? c : d : e可以重新排列以减少混淆,!a ? e : b ? c : d.
2021-05-10 21:54:50
@Roamer-1888 流程 args = !! arr // if arguments ? $.isArray(arr) // are arguments an array ? arr // return array : Array.prototype.slice.call(arguments).map(function (p) {return p.hasOwnProperty("promise") // is p jQuery promise ? p // return jQuery promise : new $.Deferred().resolve(p, null, deferred.promise()) // else return p as resolved jQuery promise } ) // else return array of promises : [deferred.resolve(deferred.promise())] // else return deferred.promise() as array
2021-05-12 21:54:50