如何使用jQuery';是否使用自定义javascript对象创建延迟对象?
我有一个标准的javascript对象,它的原型使用一个如何使用jQuery';是否使用自定义javascript对象创建延迟对象?,javascript,jquery,jquery-deferred,Javascript,Jquery,Jquery Deferred,我有一个标准的javascript对象,它的原型使用一个.start()方法进行扩展,该方法使用两个回调作为参数:success和failure。此方法执行一些异步处理(它是而不是AJAX),并根据此处理的结果调用成功或失败回调 以下是如何将其计划化: function MyObject() { } MyObject.prototype.start = function(successCallback, errorCallback) { (function(s, e) {
.start()
方法进行扩展,该方法使用两个回调作为参数:success
和failure
。此方法执行一些异步处理(它是而不是AJAX),并根据此处理的结果调用成功或失败回调
以下是如何将其计划化:
function MyObject() {
}
MyObject.prototype.start = function(successCallback, errorCallback) {
(function(s, e) {
window.setTimeout(function() {
if (Math.random() < 0.8) {
s();
} else {
e();
}
}, 2000);
})(successCallback, errorCallback);
}
此数组中元素的顺序很重要。我需要在数组的每个元素上连续触发.start()
方法,但仅在前一个元素完成后触发(即调用成功回调)。如果发生错误(调用失败回调),我希望停止执行,不再对数组的其余元素调用.start方法
我可以通过使用递归函数天真地实现这一点:
function doProcessing(array, index) {
array[index++].start(function() {
console.log('finished processing the ' + index + ' element');
if (index < array.length) {
doProcessing(array, index);
}
}, function() {
console.log('some error ocurred');
});
}
doProcessing(arr, 0);
函数数据处理(数组、索引){
数组[index++].start(函数(){
log('处理完'+index+'元素');
if(索引<数组长度){
数据处理(数组、索引);
}
},函数(){
log(“发生了一些错误”);
});
}
数据处理(arr,0);
这很好,但是看看jQuery1.5中引入的代码,我认为这段代码还有改进的余地。不幸的是,我还不觉得很舒服,我正在努力学习
所以我的问题是,是否有可能修改我的原始代码并利用这个新的API?如果有,您能给我提供一些指导吗
下面是我的实现的一个例子。您可以这样做:()
函数MyObject(){
}
MyObject.prototype.start=函数(队列){
var deferred=$.deferred();
//仅当队列中的所有其他内容都已完成并成功时才执行此操作
$.when.apply(jQuery,queue).done(function(){
setTimeout(函数(){
if(Math.random()<0.8){
延迟。解决();
}否则{
拒绝();
}
}, 2000);
});
延期归还;
}
var arr=[new MyObject(),new MyObject(),new MyObject()];
var queue=新数组();
$。每个(arr,函数(索引,值){
queue.push(value.start)(队列)
.done(函数(){
console.log('successed'+索引);
})
.fail(函数(){
console.log('failed'+索引);
}));
});
<>虽然不太确定你会认为这是一个进步。
你的实现没有错。众所周知,使用jQuery并不总是最好的方法
我会这样做:(无需修改MyObject类..)函数数据处理(数组、索引){
var defer=new$.Deferred();
$.when(延迟)。然后(数据处理);
数组[index++].start(函数(){
日志('已完成处理'+index+'元素');
if(索引<数组长度){
解析(数组、索引);
}
},函数(){
日志('出现一些错误=>中断进程');
});
};
正如您所看到的,与普通JavaScript方法相比,没有什么真正的优势
以下是我的建议:当我们编程时,记住掌握原则或指导方针是非常重要的 获得高内聚和低耦合意味着我们的代码将更好,更可重用,更易于维护 因此,类MyObject不能知道队列存在。MyObject将了解自己的特性和方法以及其他任何东西
// Class MyObject
function MyObject(name) {
this.name = name;
}
MyObject.prototype.start = function() {
var deferred = $.Deferred();
var self = this;
setTimeout(function() {
if (Math.random() <= 0.8) {
console.log(self.name + "... ok");
deferred.resolve();
} else {
console.log(self.name + "... fail");
deferred.reject();
}
}, 1000);
return deferred.promise();
}
我已经为jQuery构建了一个插件:iterativeWhen。它适用于jQuery1.8及更高版本
$.iterativeWhen = function () {
var deferred = $.Deferred();
var promise = deferred.promise();
$.each(arguments, function(i, obj) {
promise = promise.then(function() {
return obj();
});
});
deferred.resolve();
return promise;
};
jshiddle here:+1看到顶级回答者提出一个好问题总是很好的。自我回答这个问题?看起来很有趣,唯一的问题是我不能修改
MyObject
。顺便问一下,你的最终目标是什么?延迟的真正作用在于您可以将多个回调注册到回调队列中。因此,不管(a)同步函数已经完成,您仍然可以注册其他回调。此外,注册多个回调非常容易。这听起来像你需要的东西吗?我真正的目标是通过尝试看看它是否可以应用于某些场景来了解Deffered是如何工作的。你的回答在这方面很有帮助。非常感谢。
function doProcessing(array, index) {
var defer = new $.Deferred();
$.when(defer).then(doProcessing);
array[index++].start(function() {
log('finished processing the ' + index + ' element');
if (index < array.length) {
defer.resolve(array, index);
}
}, function() {
log('some error ocurred => interrupting the process');
});
};
// Class MyObject
function MyObject(name) {
this.name = name;
}
MyObject.prototype.start = function() {
var deferred = $.Deferred();
var self = this;
setTimeout(function() {
if (Math.random() <= 0.8) {
console.log(self.name + "... ok");
deferred.resolve();
} else {
console.log(self.name + "... fail");
deferred.reject();
}
}, 1000);
return deferred.promise();
}
// Create array of instances
var objectArray = [ new MyObject("A"), new MyObject("B"), new MyObject("C") ];
// Create array of functions to call start function
var functionArray = [];
$.each(objectArray, function(i, obj) {
functionArray.push(
function() {
return obj.start();
}
);
});
// Chain three start calls
$.iterativeWhen(functionArray[0], functionArray[1], functionArray[2])
.done(function() {
console.log("First: Global success");
// Chain three start calls using array
$.iterativeWhen.apply($, functionArray)
.done(function() {
console.log("Second: Global success");
})
.fail(function() {
console.log("Second: Global fail");
});
})
.fail(function() {
console.log("First: Global fail");
});
$.iterativeWhen = function () {
var deferred = $.Deferred();
var promise = deferred.promise();
$.each(arguments, function(i, obj) {
promise = promise.then(function() {
return obj();
});
});
deferred.resolve();
return promise;
};