jQuery提供的deferred.promise()方法的作用是,在原来的Deferred 对象上返回另一个 Deferred 对象,即受限制的 Promise 对象,受限制的 Promise 对象只开放与改变执行状态无关的方法(比如done()方法和fail()方法),屏蔽与改变执行状态有关的方法(比如resolve()方法和reject()方法),从而使得执行状态不能被改变。
首先看一个 Deferred对象的执行状态被改变的例子:
var dtd = $.Deferred(); // 新建一个Deferred对象 var wait = function(dtd){ var tasks = function(){ alert("执行完毕!"); dtd.resolve(); // 改变Deferred对象的执行状态 }; setTimeout(tasks,5000); return dtd; }; $.when(wait(dtd)) .done(function(){ alert("等待执行!"); }) .fail(function(){ alert("出错啦!"); }); //代码的尾部加了一行dtd.resolve(),这就改变了dtd对象的执行状态,因此导致done()方法立刻执行 dtd.resolve();// 改变Deferred对象的执行状态
再看一个 Deferred对象返回deferred.promise()的例子:
var wait = function(){ var dtd = $.Deferred(); //在函数内部,新建一个Deferred对象 var tasks = function(){ alert("执行完毕!"); dtd.resolve(); // 改变Deferred对象的执行状态 }; setTimeout(tasks,5000); return dtd.promise(); // 返回promise对象 }; $.when(wait()) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); });
wait()函数返回的是promise对象。dtd.promise().resolve()方法不存在,因此无法改变状态,然后,我们把回调函数绑定在这个对象上面,而不是原来的deferred对象上面。
这样的好处是,无法改变promise对象的执行状态,要想改变执行状态,只能操作原来的deferred对象。