Javascript jQuery延迟/承诺

Javascript jQuery延迟/承诺,javascript,jquery,promise,deferred,Javascript,Jquery,Promise,Deferred,我正在试图理解使用jQuery时承诺是如何工作的。 这是我的沙箱: function test1() { var deferred = $.Deferred() setTimeout(function() { deferred.resolve(1); //deferred.reject(2); }, 2000); return deferred.promise();

我正在试图理解使用jQuery时承诺是如何工作的。 这是我的沙箱:

    function test1() {
        var deferred = $.Deferred()
        setTimeout(function() {
             deferred.resolve(1);
             //deferred.reject(2);
        }, 2000);
        return deferred.promise();
    }

    function test2() { 
        var deferred = $.Deferred()
        setTimeout(function() {
             deferred.resolve(2);
            // deferred.reject(2);
        }, 1000); 
        return deferred.promise();
    }

    function doTest(){
        $.when(test1()).then(
            function (a) {
                console.log('test1 finished', a)
                return test2();
            },
            function (a) {
                console.log('something failed in test1', a)
            }
        ).then(
            function (b) {
                console.log("test2 finished", b);
            },
            function (b) {
                console.log("something failed in test1", b);
            }
        );
    }       
它的工作原理与我预期的一样-编写:

测试1完成了1

测试2完成了测试2

但当我改变它时,如下所示:

        function test1() {
        var deferred = $.Deferred()
        setTimeout(function() {
            // deferred.resolve(1);
             deferred.reject(2);
        }, 2000);
        return deferred.promise();
    }

    function test2() { 
        var deferred = $.Deferred()
        setTimeout(function() {
             deferred.resolve(2);
            // deferred.reject(2);
        }, 1000); 
        return deferred.promise();
    }
它将写入控制台:

test1 2中出现了一些失败

测试2未定义完成

什么是不正确的,因为test2甚至还没有被执行

我希望,“test2完成未定义”不应该显示


我猜第二个出现了问题,但是什么呢?

您的问题实际上是第一个
然后
的onRejected函数。具体来说,因为您正在“返回一个值”(未定义),所以链中的下一个
then
处理程序将此视为已实现的承诺

这在某些情况下很有用:

$.when(riskyFunction()).then(
  function (value) {
    return processValue(value);
  }, function (error) {
    console.log(error);
    return defaultValue;          // This lets you recover...
  }).then(function (value2) {
    return processValue2(value2); // so this handler runs regardless of
                                  // riskyFunction's return value.
  });
与同步代码相比,这与窄
try
块匹配:

try {
  a = test1();
  b = test2();
} catch (e) {
  console.log('something failed in test1', a)
}
console.log("test2 finished", b);  // this runs even if test1 or test2 fails,
                                   // but in those cases b is undefined!

相反,您应该删除错误处理程序并在最后捕获错误,或者至少
return$。拒绝(a)
抛出一个
,以继续跟踪
然后
处理程序中的错误链。

您或者需要在错误处理程序中调用
test2
,或者需要安装“test2 finished”-只在
test2()
promise上记录结果处理程序,否则您将不需要在错误发生之前捕获它。听起来您在jQuery 1.x/2.x中了解了延迟/承诺,现在您使用的是3.x,它的行为不同(正确)。在3.x中,默认情况下,catch处理程序(第二个参数为
.then()
)会捕获—承诺链将沿着其成功路径继续,除非抛出/重新抛出错误,或者返回(最终)拒绝的承诺。
try {
  a = test1();
  b = test2();
} catch (e) {
  console.log('something failed in test1', a)
}
console.log("test2 finished", b);  // this runs even if test1 or test2 fails,
                                   // but in those cases b is undefined!