修改后的jQuery API $ .when()在超时时返回undefined

时间:2014-05-15 00:11:46

标签: javascript jquery jquery-deferred

我尝试使用jQuery API的when()示例来举例说明我自己使用超时。

他们的:

$.when( $.ajax( "/page1.php" ), $.ajax( "/page2.php" ) ).done(function( a1, a2 ) {
  // a1 and a2 are arguments resolved for the page1 and page2 ajax requests, respectively.
  // Each argument is an array with the following structure: [ data, statusText, jqXHR ]
  var data = a1[ 0 ] + a2[ 0 ]; // a1[ 0 ] = "Whip", a2[ 0 ] = " It"
  if ( /Whip It/.test( data ) ) {
    alert( "We got what we came for!" );
  }
});

矿:

var fnOne = function(){

  setTimeout(function(){  return "one";    }, 1000);


};


var fnTwo = function(){

  setTimeout(function(){  return "two";    }, 5);

};


$(function(){

    $.when( fnOne(), fnTwo() ).then(function( a1, a2 ) {

      console.log(a1, a2);

   });


});

我得到undefined undefined。为什么不赢这项工作?顺便说一下,当我删除超时时,它可以工作。 JSBIN

2 个答案:

答案 0 :(得分:3)

$.when()需要延迟或承诺的参数。当所有这些承诺作为参数被解决时,它将自行解决。当你传递一些不是承诺的东西时,$.when()真的不知道它何时完成,所以不能做到这一点。

如果您确实希望将setTimeout()与promises API一起使用,那么您可能希望将其包装起来,以便它返回在计时器触发后解析的promise。然后,您可以像$.ajax()来电一样使用它。

这是setTimeout()的承诺包装器。它返回一个在计时器被触发并且已经调用回调并且解析它的值是回调的返回值时解析的promise:

function promiseSetTimeout(fn, t) {
    var d = $.Deferred();
    setTimeout(function() {
        d.resolve(fn());
    }, t);
    return d.promise();
}

然后,您可以将promiseSetTimeout()$.when()

一起使用
function fnOne() {
     return promiseSetTimeout(function(){  return "one";    }, 1000);
}

function fnTwo() {
     return promiseSetTimeout(function(){  return "one";    }, 1000);
}

$.when( fnOne(), fnTwo() ).then(function( a1, a2 ) {
  console.log(a1, a2);
});

工作演示:http://jsfiddle.net/jfriend00/HskLh/

答案 1 :(得分:2)

  

为什么要赢得这项工作?

由于fnOnefnTwo不会返回承诺,因此会返回undefined。功能应如下所示:

var fnOne = function(){
  var deferred = new $.Deferred();

  setTimeout(function(){  deferred.resolve("one")   }, 1000);

  return deferred;
};

否则,如果您传递除$.when的承诺之外的任何其他值,它将自动使用该值创建已解决的承诺。另外,从传递给setTimeout的回调中返回一个值对调用setTimeout的函数没有任何影响。