我有一个网页,其中异步触发了某个 Ajax 事件。这个 Ajax 部分可以被调用一次或多次。我无法控制触发此事件的次数,也无法控制时间。
此外,该 Ajax 部分中的某些代码应该作为临界区运行,这意味着,当它运行时,不应运行该代码的其他副本。
这是一个伪代码:
- 运行 JavaScript 或 jQuery 代码
- 进入临界区即Ajax(当某个进程在等待响应回调时,不要再次进入该区,直到这个过程完成)
- 运行更多 JavaScript 或 jQuery 代码
我的问题是,如何按照上述方式运行第 2 步?如何使用 JavaScript 或 jQuery 创建/保证互斥部分。
我了解理论(信号量、锁等),但我无法使用 JavaScript 或 jQuery 实现解决方案。
编辑
如果您建议使用布尔变量进入临界区,这将不起作用,下面的行将解释原因。
关键部分的代码如下(使用布尔变量建议):
load_data_from_database = function () {
// Load data from the database. Only load data if we almost reach the end of the page
if ( jQuery(window).scrollTop() >= jQuery(document).height() - jQuery(window).height() - 300) {
// Enter critical section
if (window.lock == false) {
// Lock the critical section
window.lock = true;
// Make Ajax call
jQuery.ajax({
type: 'post',
dataType: 'json',
url: path/to/script.php,
data: {
action: 'action_load_posts'
},
success: function (response) {
// First do some stuff when we get a response
// Then we unlock the critical section
window.lock = false;
}
});
// End of critical section
}
}
};
// The jQuery ready function (start code here)
jQuery(document).ready(function() {
var window.lock = false; // This is a global lock variable
jQuery(window).on('scroll', load_data_from_database);
});
现在这是使用布尔变量建议的锁定部分的代码。这将无法按以下建议工作:
用户向下滚动,(并且基于关联
jQuery(window).on('scroll', load_data_from_database);
触发了多个滚动事件。假设几乎同时触发了两个滚动事件
两者都调用
load_data_from_database
函数第一个事件检查是否
window.lock
为假(答案为真,所以如果陈述正确)第二个事件检查是否
window.lock
为假(答案为真,所以如果陈述正确)第一个事件进入if语句
第二个事件进入if语句
第一条语句设置
window.lock
为true第二个语句设置
window.lock
为true第一条语句运行 Ajax 临界区
第二条语句运行 Ajax 临界区。
两者都完成了代码
正如您所注意到的,这两个事件几乎同时被触发,并且都进入了临界区。所以锁是不可能的。