如果我有一个带有ajax调用的函数,该函数从数据库中获取了一些值,然后需要将该值发送回php脚本,依此类推,我该如何声明此变量?
function call(id){
$.ajax({
. . .
data: {id: id},
success: function(res){
window.id = res.id
}
});
}
//first call the function with a value
call(10);
//then call it with the returned value every time the btn gets clicked
$('#btn').click(function(){
call(window.id);
})
根据我的理解,使用像这样的全局变量是一种不好的做法,因为全局范围已经很拥挤,脚本查找变量需要更长的时间。我可以通过让我将其发送回而不是全局的方式来定义此值吗?
答案 0 :(得分:4)
避免全局变量的最简单方法是首先不在全局范围内工作。这样做的方法是创建一个IIFE(立即调用函数表达式),它是一个在全局范围内的匿名函数,但是由于它是匿名的,因此它没有机会与具有相同功能的另一个函数发生冲突。名称。它会立即被调用,以便其中的代码可以执行(类似于init
这种操作)。然后,在该函数内,您可以执行通常的操作。然后在此处创建IIFE范围(而非全局范围)变量。
// IIFE wrapper
(function(){
let mainID = null; // IIFE scoped variable
function call(id){
$.ajax({
. . .
data: {id: id},
success: function(res){
mainID = res.id; // Set the IIFE scoped variable to the AJAX result
}
});
}
// Set up the event
$('#btn').click(function(){
all(res.id); // <-- And, you can use it anywhere in the IIFE
});
call(10); // first call the function with a value
})(); // <-- The extra set of parenthesis is what invokes the expression
另一方面,即使在适当的位置,您的代码也无法正常工作,因为您要在AJAX调用有机会完成之前设置按钮的click
事件处理程序。仅仅因为该代码位于异步代码之后,并不意味着它将在异步代码之后执行。异步操作的全部要点是我们不知道它何时会完成,并且由于JavaScript在单线程环境中运行,而异步操作正在进行中,因此当前功能会运行到完成。仅在当前线程空闲之后,才会调用异步操作(成功回调)的结果。如果事件处理程序依赖于AJAX调用的结果,则需要在“成功”回调中设置事件处理程序,因此无论如何对于全局毫无意义。您仍然应该将所有代码都放在IIFE中,因为这是最佳实践。
这是一个示例,显示了另一种类型的异步操作(计时器),该操作仍然像您的AJAX调用那样操作,从而显示了问题:
// Global variable
var result = null;
// Start an async operation that will execute the callback
// after three seconds:
setTimeout(function(){
result = "complete"
console.log("Async operation " + result);
}, 3000);
// This function will run before the async operation
// completes, so the use of the variable that is set
// by the async operation will fail
console.log("Local operation " + result);
因此,实际上,您甚至根本不需要全局变量,只需将事件绑定代码移到成功回调中即可。从用户界面的角度来看,您可能希望按钮从禁用开始,然后在成功回调中将其启用,以便在设置click
处理程序之前无法单击它。
// IIFE wrapper
(function(){
function call(id){
$.ajax({
. . .
data: {id: id},
success: function(res){
// Set up the event now that the AJAX call is complete
$('#btn').click(function(){
call(res.id);
});
}
});
}
call(10); // first call the function with a value
})(); // <-- The extra set of parenthesis is what invokes the expression
这是整个情况的可行示例:
(function(){
// IIFE scoped variables
let btn = document.querySelector("button");
let random = null;
function async(){
// Async operation complete!
// Generate a random number that simulates the
// DB response that would now be available
random = Math.floor(Math.random() * 11);
// Enable the button:
btn.removeAttribute("disabled");
// Set up the button's click event handler
btn.onclick = function(){
console.log("Button clicked. ID = " + random);
async();
};
}
// Start an async operation that will execute the callback
// after three seconds:
setTimeout(async, 3000);
})();
<button type="button" disabled>Click Me</button>
答案 1 :(得分:0)
由于id
在语义上与#btn
相关联,因此您可以将返回的id
值存储为#btn
属性:
function call(id){
$.ajax({
. . .
data: {id: id},
success: function(res){
$('#btn').prop('response_id', res.id);
}
});
}
//first call the function with a value
call(10);
//then call it with the returned value every time the btn gets clicked
$('#btn').click(function(){
call(this.prop('response_id'));
})
答案 2 :(得分:-3)
只需将window.id
替换为call.id
(即,将其存储为函数的属性):
function call(id){
$.ajax({
. . .
data: {id: id},
success: function(res){
call.id = res.id
}
});
}
//first call the function with a value
call(10);
//then call it with the returned value every time the btn gets clicke
$('#btn').click(function(){
call(call.id);
})