Jos*_*rke 34 javascript concurrency asp.net-ajax
我有一个名为save()的函数,该函数收集页面上的所有输入,并对服务器执行AJAX调用以保存用户工作的状态.
当用户单击保存按钮时,当前调用save(),或执行一些需要我们在服务器上具有最新状态的其他操作(例如,从页面生成文档).
我正在增加每隔一段时间自动保存用户工作的能力.首先,我想阻止AutoSave和用户生成的保存同时运行.所以我们有以下代码(我正在削减大部分代码,这不是1:1,但应该足以让我们了解这个想法):
var isSaving=false;
var timeoutId;
var timeoutInterval=300000;
function save(showMsg)
{
//Don't save if we are already saving.
if (isSaving)
{
return;
}
isSaving=true;
//disables the autoSave timer so if we are saving via some other method
//we won't kick off the timer.
disableAutoSave();
if (showMsg) { //show a saving popup}
params=CollectParams();
PerformCallBack(params,endSave,endSaveError);
}
function endSave()
{
isSaving=false;
//hides popup if it's visible
//Turns auto saving back on so we save x milliseconds after the last save.
enableAutoSave();
}
function endSaveError()
{
alert("Ooops");
endSave();
}
function enableAutoSave()
{
timeoutId=setTimeOut(function(){save(false);},timeoutInterval);
}
function disableAutoSave()
{
cancelTimeOut(timeoutId);
}
Run Code Online (Sandbox Code Playgroud)
我的问题是这段代码是否安全?主流浏览器是否一次只允许一个线程执行?
我曾经想过,如果用户点击保存并且没有响应会更糟糕,因为我们正在自动保存(而且我知道如何修改代码来处理这个问题).有人在这看到任何其他问题吗?
Jon*_*ust 44
浏览器中的JavaScript是单线程的.您将只在任何时间点处于一个功能中.功能将在输入下一个功能之前完成.你可以指望这种行为,所以如果你在你的save()功能中,你将永远不会再次输入它,直到当前的一个完成.
当你有异步服务器请求(或setTimeouts或setIntervals)时,这有时会让人感到困惑(但仍然是真的),因为这样你的函数就会被交错.他们不是.
在您的情况下,虽然两个save()呼叫不会相互重叠,但您的自动保存和用户保存可以背靠背进行.
如果您只想每隔x秒执行一次保存,则可以在保存功能上执行setInterval并忘记它.我认为不需要isSaving国旗.
我认为您的代码可以简化很多:
var intervalTime = 300000;
var intervalId = setInterval("save('my message')", intervalTime);
function save(showMsg)
{
if (showMsg) { //show a saving popup}
params=CollectParams();
PerformCallBack(params, endSave, endSaveError);
// You could even reset your interval now that you know we just saved.
// Of course, you'll need to know it was a successful save.
// Doing this will prevent the user clicking save only to have another
// save bump them in the face right away because an interval comes up.
clearInterval(intervalId);
intervalId = setInterval("save('my message')", intervalTime);
}
function endSave()
{
// no need for this method
alert("I'm done saving!");
}
function endSaveError()
{
alert("Ooops");
endSave();
}
Run Code Online (Sandbox Code Playgroud)
所有主流浏览器仅在页面上支持一个javascript线程(除非您使用Web worker).
但是,XHR请求可以是异步的.但只要您在当前保存返回请求之前禁用保存功能,一切都应该正常.
我唯一的建议是确保以某种方式向用户指示自动保存发生时(禁用保存按钮等).
| 归档时间: |
|
| 查看次数: |
12913 次 |
| 最近记录: |