如果不懂 $.when() 方法的请看我的上一篇博客
/**
* 定义一个很耗时的 wait 函数
* 这个地方不调用 resolve 就可以执行, 是因为 wait 并不是一个 promise 或者 deferred
* done()方法会立即执行,起不到回调函数的作用
* $.when()的参数只能是deferred对象,所以必须对wait()进行改写
*/
var wait = function() {
var tasks = function() {
console.log('执行完毕');
}
setTimeout(tasks, 2000)
}
$.when(wait())
.done(function() { console.log("哈哈,成功了!"); })
.fail(function() { console.log("出错啦!"); });
/**
* 改写 wait()
* 再 wait 函数执行完之后, 函数内部调用了成功的方法就会自动运行 done 函数
* 当然你也可以 调用失败的方法, 只需要把 `dtd.resolve()` 改成 `dtd.reject()` 即可
* Deferred 是有三个状态的
* 第一个状态 : 待开始的状态
* 第二个状态 : 成功时的状态
* 第三个状态 : 失败时的状态
*/
// 第一种写法(没有封装)
var dtd = $.Deferred() // 创建一个 Deferred 对象
var wait = function(dtd) { // 要求传入一个 deferred 对象, 不然这个函数没有意义了
var tasks = function() {
//这里可以有大量的复杂操作
console.log("执行完毕"); // 执行完毕
dtd.resolve() // 表示异步任务已经完成, 改变 deferred 对象的状态
// dtd.reject() // 表示异步任务失败, 改变 deferred 对象的状态
}
setTimeout(tasks, 2000) // 等待 2m 后执行
return dtd // 一定要有返回值, 并且 一定是这个 对象
}
$.when(wait(dtd))
.done(function() { console.log("哈哈,成功了!"); }) // 哈哈,成功了!
.fail(function() { console.log("出错啦!"); });
// 第二种写法 (封装版)
function waitHandle() {
var dtd = $.Deferred()
var wait = function(dtd) {
var tasks = function() {
console.log('执行完毕') // 执行完毕
dtd.resolve()
// dtd.reject()
}
setTimeout(tasks, 2000)
return dtd
}
return wait(dtd)
}
var w = waitHandle()
// 此处同样可是使用 then 方法来调用
w.then(function() {
console.log('ok 1'); // ok 1
}, function() {
console.log('err 1');
}).then(function() {
console.log('ok 1'); // ok 1
}, function() {
console.log('err 1');
})
/**
* 这样呢 : 有一个弊端就是, 可以手动修改状态.
* 举梨 : 比如 我们函数中, 定义的是 dtd.resolve() 方法,但是我们再程序的最后一行加上 w.reject()
* 结果 就很有意思了, 会再程序以执行的时候, 改变 dtd 的状态, 然后立即执行 `done()`, 等到 延时器 结束的时候再执行 `console.log('执行完毕')`
* 这样就不是我们想要的了
* 所以 : 就引出了 deferred.promise() 方法.
*/
// + w.resolve()