jQuery延迟对象 - catch与fail的区别

5

我希望确认没有遗漏的技巧;在Kris Kowal的库中,您可以将以下代码作为Promise中通用的异常处理语句:

var a, b, c, d, e, f;

readFile('fileA')
    .then(function (res) {
        a = res;

        return readFile('fileB');
    })
    .then(function (res) {
        b = res;

        return readFile('fileC');
    })
    .then(function (res) {
        c = res;

        return readFile('fileD');
    })
    .then(function (res) {
        d = res;

        return readFile('fileE');
    })
    .then(function (res) {
        e = res;

        return readFile('fileF');
    })
    .then(function () {
        f = res;
    })
    .catch(function () {
        // error happened in file read *somewhere* (don't care where)
    });

在jQuery的延迟对象中,没有catch语句,相反,我必须这样做:
var a, b, c, d, e, f;

readFile('fileA')
    .then(function (res) {
        a = res;

        return readFile('fileB');
    })
    .fail(function () {
        // error happened in file read *somewhere* (don't care where)
    })
    .then(function (res) {
        b = res;

        return readFile('fileC');
    })
    .fail(function () {
        // error happened in file read *somewhere* (don't care where)
    })
    .then(function (res) {
        c = res;

        return readFile('fileD');
    })
    .fail(function () {
        // error happened in file read *somewhere* (don't care where)
    })
    .then(function (res) {
        d = res;

        return readFile('fileE');
    })
    .fail(function () {
        // error happened in file read *somewhere* (don't care where)
    })
    .then(function (res) {
        e = res;

        return readFile('fileF');
    })
    .fail(function () {
        // error happened in file read *somewhere* (don't care where)
    })
    .then(function (res) {
        f = res;

        return readFile('fileF');
    })
    .fail(function () {
        // error happened in file read *somewhere* (don't care where)
    });

很遗憾,每个then分支都有独特的逻辑。我是否漏掉了什么,或者上面jQuery版本是实现Kris Kowal的q库等效的唯一方法?


1
你尝试过使用链式then()并在最后使用单个.fail();吗?这应该可以解决问题。 - T J
这是Sebastien经常遇到的问题,我仍然不确定你是否可以用fail替换catch。 - A. Wolff
@A.Wolff 啊.. 谁是Sebastien..? 另一只狼..? ._. - T J
2
@keldar,问题的一部分在于jQuery在Promises/A+标准化之前就添加了Deferreds(我的理解是,很多标准化工作都是在开发人员从jQuery的deferreds中学习promise-like行为后进行的)。幸运的是,jQuery 3将兼容Promises/A+ - zzzzBov
2
简而言之,jQuery的.fail()方法不会捕获异常,也不能被强制执行。在调用fail()后,所在的链路会确保一直沿着错误路径执行。与此相反的是,.then()方法的错误处理器并不会自动捕获异常,但可以通过返回一个resolved promise来实现;如果返回其它任何东西,都会更改沿着错误路径传递的“失败原因”。 - Roamer-1888
显示剩余7条评论
1个回答

3
假设readFile返回一个Promise对象,您可以使用$.when()异步加载所有文件(当然,如果您不关心读取文件的顺序):
来自文档:
在将多个Deferred对象传递给jQuery.when()的情况下,该方法返回一个新的“主”Deferred对象的Promise,该对象跟踪它所传递的所有Deferred对象的聚合状态。一旦所有Deferred解析或拒绝了,该方法将解析其主Deferred,或者一旦拒绝其中一个Deferred,就会拒绝主Deferred。如果解析了主Deferred,则执行主Deferred的doneCallbacks。传递给doneCallbacks的参数提供每个Deferred的已解析值,并与传递给jQuery.when()的Deferred的顺序匹配。
(强调是我的)
$.when(readFile('fileA'), readFile('fileB'), readFile('fileC'), readFile('fileD'), readFile('fileE'), readFile('fileF'))
.then(function(a, b, c, d, e, f) {
    // big success
},function() {
    // error happened in file read *somewhere* (don't care where)
});

并行运行它们,而不是按顺序运行。 - A. Wolff
看了他们的文档,我肯定可以这样做 $.when(readFile('fileA'), readFile('fileB'), ..., readFile('fileF')).then(function (a, b, ..., f) {...}); 其中 a, b, ..., f 是文件的内容? - keldar
@keldar 是的,为了更清晰起见,我更新了答案。请注意,你的readFile方法应该返回一个延迟对象。 - T J
谢谢@TJ。同意 - 它确实可以(或者公平地说是延迟的承诺)。 - keldar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接