首页 > 语言 > JavaScript > 正文

在jQuery1.5中使用deferred对象 着放大镜看Promise

2024-05-06 14:25:06
字体:
来源:转载
供稿:网友
引言
在那篇经典的关于jQuery1.5中Deferred使用方法介绍的文章中(译文见这里),有下面一段描述:

$.ajax() returns an object packed with other deferred-related methods. I discussed promise(), but you'll also find then(), success(), error(), and a host of others. You don't have access to the complete deferred object, though; only the promise, callback-binding methods, and the isRejected() and isResolved() methods, which can be used to check the state of the deferred.
But why not return the whole object? If this were the case, it would be possible to muck with the works, maybe pragmatically "resolve" the deferred, causing all bound callbacks to fire before the AJAX request had a chance to complete. Therefore, to avoid potentially breaking the whole paradigm, only return the dfd.promise().


这段话非常令人费解,我也是看了几遍才看明白。大致的意思是:
$.ajax()返回一个对象(jqXHR,这是对原生的XMLHttpRequest的封装),这个对象包含了deferred相关的函数,比如promise(), then(), success(), error(), isRejected(), isResolved()。
但是你发现没,这里面没有resolve(), resolveWith(), reject(), rejectWith() 几个函数,而这几个函数才是用来改变deferred对象流程。也就是说$.ajax()返回了一个只读的deferred对象。

下面erichynds改用反问的语气提出,为什么不返回完整的deferred对象,而只返回只读的deferred对象?
如果返回完整的deferred对象,那么外部程序就能随意的触发deferred对象的回调函数,很有可能在AJAX请求结束前就触发了回调函数(resolve),这就是与AJAX本身的逻辑相违背了。
所以为了避免不经意间改变任务的内部流程,我们应该只返回deferred的只读版本(dfd.promise())。


为了说明$.ajax()和$.Deferred()返回的deferred对象的不同,请看下面的例子:
代码如下:
// deferred对象所有的方法数组
var methods = 'done,resolveWith,resolve,isResolved,then,fail,rejectWith,reject,isRejected,promise'.split(','),
method,
ajaxMethods = [],
onlyInDeferredMethods = [];
for (method in $.ajax()) {
if ($.inArray(method, methods) !== -1) {
ajaxMethods.push(method);
}
}

for (method in $.Deferred()) {
if ($.inArray(method, methods) !== -1 && $.inArray(method, ajaxMethods) === -1) {
onlyInDeferredMethods.push(method);
}
}
// 存在于$.Deferred(),但是不存在于$.ajax()的deferred相关方法列表为:
// ["resolveWith", "resolve", "rejectWith", "reject"]
console.log(onlyInDeferredMethods);

反面教材
如果$.ajax()返回的对象包含resolve(), resolveWith(),可能会产生哪些影响呢?
我们还是用例子也说明,首先看看erichynds原文的第一个例子:
代码如下:
// $.get, 异步的AJAX请求
var req = $.get('./sample.txt').success(function (response) {
console.log('AJAX success');
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选