- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
我有一个网页,其中某个 Ajax 事件是异步触发的。这个 Ajax 部分可以被调用一次或多次。我无法控制此事件被触发的次数,也无法控制时间。
此外,该 Ajax 部分中的特定代码应作为关键部分运行,这意味着,当它运行时,该代码的其他副本不应运行。
伪代码如下:
我的问题是,如何按照上述方式运行第 2 步?如何使用 JavaScript 或 jQuery 创建/保证互斥部分。
我了解理论(信号量、锁等),但我无法使用 JavaScript 或 jQuery 实现解决方案。
编辑
如果您建议使用 bool 变量进入临界区,这是行不通的,下面几行将解释原因。
关键部分的代码如下(使用 bool 变量建议):
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);
});
现在这是使用 bool 变量建议的锁定部分的代码。这不会像下面建议的那样工作:
用户向下滚动,(并基于关联 jQuery(window).on('scroll', load_data_from_database);
触发了不止一个滚动事件。
假设两个滚动事件几乎同时触发
都调用load_data_from_database
函数
第一个事件检查 window.lock
是否为 false(答案为真,因此 if 语句正确)
第二个事件检查 window.lock
是否为 false(答案为真,因此 if 语句正确)
第一个事件进入if语句
第二个事件进入if语句
第一个语句将 window.lock
设置为 true
第二条语句将window.lock
设置为true
第一个语句运行 Ajax 临界区
第二条语句运行 Ajax 临界区。
都完成代码
正如您所注意到的,这两个事件几乎同时被触发,并且都进入了临界区。所以锁是不可能的。
最佳答案
我认为您在上面提供的最有用的信息是您对锁定的分析。
The user scrolls down, (and based on the association
jQuery(window).on('scroll', load_data_from_database);
more than one scroll event is triggered.Assume two scroll events are triggered right at almost the same moment
Both call the
load_data_from_database
functionThe first event checks if
window.lock
is false (answer is true, so if statement is correct)The second event checks if
window.lock
is false (answer is true, so if statement is correct)
这立刻告诉我您遇到了一个常见的(并且非常直观的)误解。
Javascript 是异步的,但异步代码与并发代码不同。据我了解,“异步”意味着函数的子例程不一定像我们在同步代码中所期望的那样按深度优先顺序进行探索。一些函数调用(您称为“ajax”的函数调用)将被放入队列中并稍后执行。这可能会导致一些令人困惑的代码,但没有什么比认为您的异步代码正在并发运行更令人困惑的了。 “并发”(如您所知)是指来自不同函数的语句可以相互交错。
像锁和信号量这样的解决方案并不是考虑异步代码的正确方式。 Promises是正确的方法。这就是让网络编程变得有趣和酷的东西。
我不是 promise 大师,但这里有一个 working fiddle这(我认为)证明了一个修复。
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) {
console.log(promise.state());
if (promise.state() !== "pending") {
promise = jQuery.ajax({
type: 'post',
url: '/echo/json/',
data: {
json: { name: "BOB" },
delay: Math.random() * 10
},
success: function (response) {
console.log("DONE");
}
});
}
}
};
var promise = new $.Deferred().resolve();
// The jQuery ready function (start code here)
jQuery(document).ready(function() {
jQuery(window).on('scroll', load_data_from_database);
});
我正在使用全局 promise 来确保您的事件处理程序的 ajax 部分仅被调用一次。如果您在 fiddle 中上下滚动,您会看到在处理 ajax 请求时,不会发出新请求。 ajax 请求完成后,可以再次发出新请求。运气好的话,这就是您要寻找的行为。
但是,我的回答有一个非常重要的警告:众所周知,jQuery 的 promises 实现是错误的。这不仅仅是人们说的听起来很聪明,它实际上非常重要。我建议使用不同的 promise 库并将其与 jQuery 混合使用。如果您刚刚开始学习 Promise,这一点尤其重要。
编辑:就个人而言,我最近和你处在同一条船上。仅仅 3 个月前,我还认为我使用的一些事件处理程序是交错的。当人们开始告诉我 javascript 是单线程的时,我感到震惊和难以置信。对我有帮助的是了解触发事件时会发生什么。
在同步编码中,我们习惯于“帧”“堆栈”的概念,每个“帧”代表一个函数的上下文。在 javascript 和其他异步编程环境中,堆栈由队列扩充。当您在代码中触发事件,或使用像 $.ajax
调用这样的异步请求时,您会将事件推送到此队列。下次堆栈清空时将处理该事件。因此,例如,如果您有以下代码:
function () {
this.on("bob", function () { console.log("hello"); })
this.do_some_work();
this.trigger("bob");
this.do_more_work();
}
do_some_work
和 do_more_work
这两个函数将一个接一个地立即触发。然后该函数将结束,您入队的事件将开始一个新的函数调用(在堆栈上)并且“hello”将出现在控制台中。如果在处理程序中触发事件,或者在子例程中触发事件,事情会变得更加复杂。
一切都很好,但是当您想要处理异常时,事情开始变得非常糟糕。在您进入异步领域的那一刻,您就留下了“函数应返回或抛出”的美丽誓言。如果你在一个事件处理程序中,你抛出一个异常,它会在哪里被捕获?这,
function () {
try {
$.get("stuff", function (data) {
// uh, now call that other API
$.get("more-stuff", function (data) {
// hope that worked...
};
});
} catch (e) {
console.log("pardon me?");
}
}
现在不会救你了。 Promises 允许您通过将回调链接在一起并控制它们返回的地点和时间来收回这个古老而强大的誓言。因此,使用一个不错的 promises API(而不是 jQuery),您可以将这些回调以一种允许您以您期望的方式冒泡异常并控制执行顺序的方式链接起来。在我看来,这就是 promise 的美丽和魔力。
如果我完全不在,有人会阻止我。
关于javascript - JavaScript 或 jQuery 中的临界区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22150960/
在带有 jQuery 的 CoffeeScript 中,以下语句有什么区别吗? jQuery ($) -> jQuery -> $ - > 最佳答案 第一个与其他两个不同,就像在纯 JavaScr
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭13 年前。 Improve th
就目前情况而言,这个问题不太适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、民意调查或扩展讨论。如果您觉得这个问题可以改进并可能重新开放,visit
这个问题可能听起来很愚蠢,但请耐心等待,因为我完全是初学者。我下载了两个 jQuery 版本,开发版本和生产版本。我想知道作为学习 jQuery 的初学者,什么更适合我。 最佳答案 如果您对 jQue
The documentation说要使用 1.6.4,但我们现在已经升级到 1.7.2。 我可以在 jQuery Mobile 中使用最新版本的 jQuery 吗? 最佳答案 您当然可以,但如果您想
我在这里看到这个不错的 jquery 插件:prettyphoto jquery lightbox有没有办法只用一个简单的jquery来实现这样的效果。 我只需要弹出和内联内容。你的回复有很大帮助。
很明显我正在尝试做一些 jQuery 不喜欢的事情。 我正在使用 javascript 上传图片。每次上传图片时,我都希望它可见,并附加一个有效的删除脚本。显示工作正常,删除则不然,因为当我用 fir
这两个哪个是正确的? jQuery('someclass').click(function() { alert("I've been clicked!"); }); 或 jQuery('somec
我正在寻找一个具有以下格式的插件 if (jQuery)(function ($) { -- plugin code -- })(jQuery); 我明白 (function ($)
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭10 年前。 Improv
我知道这个问题已经被问过几次了,但想知道您是否可以帮助我解决这个问题。 背景:我尝试创建一个使用 Ajax 提交的表单(jQuery 表单提交)。我已经工作得很好,然后我想在表单上得到验证。我可以使用
我正在使用无处不在的jquery validate plugin用于表单验证。它支持使用metadata plugin用于向表单元素添加验证规则。 我正在使用此功能。当验证查找这些规则时,它会对元素进
我更喜欢为我一直在开发的网络社区添加实用的视觉效果,但随着事情开始堆积,我担心加载时间。 拥有用户真的更快吗加载(希望是缓存的)副本来自 Google 存储库的 jquery? 是否使用 jQuery
这个问题已经有答案了: Slide right to left? (17 个回答) 已关闭 9 年前。 你能告诉我有没有办法在 jQuery 中左右滑动而不使用 jQuery UI 和 jQuery
我如何找出最适合某种情况的方法?任何人都可以提供一些示例来了解功能和性能方面的差异吗? 最佳答案 XMLHttpRequest 是原始浏览器对象,jQuery 将其包装成一种更有用和简化的形式以及跨浏
运行时 php bin/console oro:assets:build ,我有 11 个这样的错误: ERROR in ../node_modules/jquery-form/src/jquery.
我试图找到 jQuery.ajax() 在源代码中的定义位置。但是,使用 grep 似乎不起作用。 在哪里? 谢谢。 > grep jQuery.ajax src/* src/ajax.js:// B
$.fn.sortByDepth = function() { var ar = []; var result = $([]); $(this).each(function()
我的页面上有多个图像。为了检测损坏的图像,我使用了在 SO 上找到的这个。 $('.imgRot').one('error',function(){ $(this).attr('src','b
我在理解 $ 符号作为 jQuery 函数的别名时遇到了一些麻烦,尤其是在插件中。你能解释一下 jQuery 如何实现这种别名:它如何定义 '$' 作为 jQuery 函数的别名?这是第一个问题。 其
我是一名优秀的程序员,十分优秀!