异步的那些事(二)--Deferred

jquery1.5以后,ajax的使用发生了变化。

下面是jquery1.5以前,ajax只能这样写,此时ajax是一个XHR对象:

jquery1.5之后,ajax可以这样写,这时ajax是一个promise对象:

咦,看着这个调用是否有点眼熟,跟现在es6引入的Promise标准很像呢。其实jquery1.5应该多年前就出来了,然后慢慢成为现在的Promise标准。

我们要明确这种写法:无法改变JS异步和单线程的本质,只能从写法上杜绝callback的形式,虽然它只是一种语法糖,但是却解耦了代码,很好地体现了开放封闭的原则。

但是ajax的这种比较好的写法是如何实现的呢?下面将从基础一步步实现这样一个异步的封装。

上面的代码是一个非常简单的异步操作。但是现在我们要丰富task函数体,而不是只是执行一个输出,而是要执行很多特别复杂的代码。而且万一这个函数体要经常修改,如果直接将代码写在上图中的位置,那么可以说这是一段很失败的代码。jquery1.5以后,引入了Deferred对象,让我们用它把上面的代码封装一下。

经过简单的封装,我们已经可以对w进行.then操作。还可以进行.fail() 、.done()等其他方法。在代码中,task中执行defer.resolve()则触发.done和.then中第一个函数体。执行defer.reject()则触发.fail()、.then()中第二个函数体。

我们再来看一段操作:

从上面的代码可以看出,不在task函数体中执行resolve和reject,而是在外面主动触发w.resolve()。这时执行结果与在task执行体中执行resolve的结果是相反的。

$.Deferred()的API可分成两类:第一类:deferred.resolve , deferred.reject 。第二类: deferred.then, deferred.done, deferred.fail。第一类是主动触发,第二类是被动监听。这两种方法在实际开发中要分开。然而除了开发人员在实际开发中注意这个问题,jquery也提供了方法,随后jquery引入了promise的概念。让我们来看下面的代码

上面两段代码很好的说明了问题,第一段代码表明返回deferred.promise()仍然可以正常工作,而第二段代码说明当返回deferred.promise()的时候,则不可以在外面触发w.resolve()。这样也防止了‘不老实的人’的误操作。

你可能感兴趣的:(异步的那些事(二)--Deferred)