我的foreach循环:
jQuery(".custom-checkbox").each(function() {
if (jQuery(this).attr('data-action') == 'true') {
if(deleteQuoteItemFromListing(jQuery(this).attr('data-id'))){
console.log('passed');
}else{
console.log('failed');
}
}
});
功能是(它使用原型)但它成功了
function deleteQuoteItemFromListing(id){
//does someoperations and on success
delurl = getDelUrl()+id; //baseurl/module/action/delete/id
new Ajax.Request(delurl,{
method: 'get',
onSuccess: function(transport){
return TRUE;
}
})
}
但问题是所有foreach一次执行,并且不等待函数的响应。即使操作成功,也会打印failed
。
更新
我首先尝试的另一种方式是
jQuery('.delete-from-quote').click(function() {
var i = 0, j = 0;
jQuery(".custom-checkbox").each(function() {
if (jQuery(this).attr('data-action') == 'true') {
i++;
}
});
if (i == 0) {
alert('please choose product');
return false;
}
jQuery(".custom-checkbox").each(function() {
if (jQuery(this).attr('data-action') == 'true') {
var urlData = "<?php echo $this->getUrl('qquoteadv/index/delete/'); ?>";
urlData += "id/" + jQuery(this).attr('data-id') + "/"
var ajax = jQuery.ajax({
type: "GET",
url: urlData,
success: function(msg) {
j++;
}
})
}
if(i==j){location.reload();} //after completing all, reload the page
});
});
问题是知道所有操作已完成并重新加载页面。
答案 0 :(得分:3)
我的猜测是你省略的代码是进行异步ajax调用。由于默认情况下ajax是异步的,因此您在那里编写的代码($.ajax
或其他)启动进程,但随后代码继续运行时,该进程将在后台继续。
没有合理的方法让deleteQuoteItemFromListing
函数等待以获得响应。 (虽然它可以执行同步 ajax,A)但它通过锁定浏览器UI会导致糟糕的用户体验,并且B)jQuery将在某个阶段删除该选项,强制执行如果你想继续这样做,你可以直接去XHR。)
相反,通过让您的函数返回promise或接受回调,然后解析promise或在完成后调用回调来重构您的代码以包含Web编程的异步性质。
这里概述了承诺版本的样子:
jQuery(".custom-checkbox").each(function() {
if (jQuery(this).attr('data-action') == 'true') {
deleteQuoteItemFromListing(jQuery(this).attr('data-id'))
.done(function(id) {
console.log(id + ' passed');
})
.fail(function(id) {
console.log(id + ' failed');
});
}
});
function deleteQuoteItemFromListing(id){
var d = jQuery.Deferred();
jQuery.ajax(/*...*/)
.done(function() { // This bit assumes the deletion worked if
d.resolveWith(id); // the ajax call worked, and failed if the
}) // ajax call failed; if instead the ajax
.fail(function() { // call always works and returns a flag,
d.rejectWith(id); // adjust accordingly
});
return d.promise();
}
答案 1 :(得分:2)
使用回调可确保执行该功能。
jQuery(".custom-checkbox").each(function () {
if (jQuery(this).attr('data-action') == 'true') {
deleteQuoteItemFromListing(jQuery(this).attr('data-id'), handleData);
}
});
function handleData(data) {
if (data) {
console.log('passed');
} else {
console.log('failed');
}
}
function deleteQuoteItemFromListing(id, callback) {
//does someoperations and on success
delurl = getDelUrl() + id; //baseurl/module/action/delete/id
new Ajax.Request(delurl, {
method: 'get',
onSuccess: function (transport) {
callback(true);
}
})
}
我希望这对你有用。你需要在另一个函数之外定义handleData函数。
答案 2 :(得分:1)
(部分)您的问题出在这个简单的陈述中:
return TRUE;
在JavaScript中,“true”布尔值以小写形式写出:
return true;
解释器认为TRUE
是一个变量,并且会抛出一个ReferenceError
,因为它没有在任何地方设置/定义,这意味着该函数永远不会返回true
。
答案 3 :(得分:1)
使用jquery时。
您需要将Deferred数组中的Deferred排队,然后立即应用所有函数。
如果一个人失败,所有人都会失败,如果一切都成功,所有人都会失败。
var queue = [];
var items = 0;
return new $.Deferred(function (deferred) {
$(".custom-checkbox").each(function () {
if ($(this).attr('data-action') == 'true') {
items++;
queue.push(function () {
new Ajax.Request(delurl, {
method: 'get',
onSuccess: function (transport) {
items--;
if(items === 0)
deferred.resolve();
},
onError:function(e){
deferred.reject(e);
}
});
});
}
});
//now resolve all of the deferred fns
$.when(queue).done(function(){
console.log('All went well');
})
.fail(function(e){
console.log('Error ' + e);
});
});