Promises 和 Deferred :虽然在 Deferred 对象上调用了 .resolve() ,但调用了 .done() 和 .then()

Promises and Deferred : .done() and .then() called though .resolve() is called on the Deferred object

我是 Javascript 和 JQuery 的新手。根据我的理解,.then() 和 .done() 是由于延迟对象上的 resolve() 而触发的。但是在我的代码中,虽然没有调用 resolve(),但是 .then() 和 .done() 被触发了

<head>
    <meta charset="UTF-8">
    <title>Testing Promises</title>
</head>

<body>

<button type="button" onclick="test()"> Click Me</button>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script>

    function test() {
        var promise = $.when(another);
        promise.done(function () {
            console.log("another() done");
        });

        promise.done(function () {
            console.log("another() done 2");
        });

        promise.done(function () {
            console.log("another() done 3");
        });

        promise.fail(function (error) {
            console.log("Failed with error = ", error);
        });

        promise.then(function () {
            console.log("In then():");
        });

        console.log("test() done");
    }


    function another() {
        var def = $.Deferred();

        console.log("In another()");
        return def.promise();
    }
</script>

</body>

</html>

您正在传递 $.when 一个 函数,而不是一个承诺。它期待承诺。如果你给它传递一个承诺(通过实际调用 another),你会得到你期望的行为:

function test() {
  var promise = $.when(another());
  //                          ^^-------------- change is here
  promise.done(function() {
    console.log("another() done");
  });

  promise.done(function() {
    console.log("another() done 2");
  });

  promise.done(function() {
    console.log("another() done 3");
  });

  promise.fail(function(error) {
    console.log("Failed with error = ", error);
  });

  promise.then(function() {
    console.log("In then():");
  });

  console.log("test() done");
}


function another() {
  var def = $.Deferred();
  // Added for testing - start
  setTimeout(function() {
    console.log("waiting...");
  }, 400);
  setTimeout(function() {
    console.log("waiting...");
  }, 800);
  setTimeout(function() {
    console.log("resolving...");
    def.resolve();
  }, 1200);
  // Added for testing - end

  console.log("In another()");
  return def.promise();
}
<button type="button" onclick="test()">Click Me</button>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>

$.when(another)another 函数的(立即实现的)承诺。你会想要使用

var promise = $.when(another());

或者只是

var promise = another();

实际调用该函数并创建从未解析的 def