在我的应用程序中,我有一个submitSuccesscallback
函数,当提交成功时,它将从我自己的JS库中触发。
在submitSuccesscallback
内,我首先显示一个加载器并进行一些初始化操作。
function submitSuccesscallback(){
showLoadingIndicator(); // has code a display loader
doSubmitSuccessOperations();// has code to do some app specific operations
}
此处doSubmitSuccessOperations()
大约需要5秒才能完成执行。
现在我的问题是上面的代码在我得到showLoadingIndicator()
后不显示加载器(即ui从submitSuccesscallback()
更改)到5秒。
如果我更改下面的submitSuccesscallback(),我可以在触发submitSuccesscallback()后立即看到加载器。
function submitSuccesscallback(){
showLoadingIndicator(); // has code a display loader
setTimeout(doSubmitSuccessOperations, 1000);
}
现在我想知道的是
1)setTimeout让我的doSubmitSuccessOperations()
在后台运行吗?
2)我清楚地感觉到doSubmitSuccessOperations()
阻止了UI操作,JS中是否存在UI线程和后台线程的概念?
3)上述setTimeout
的其他选择吗?
答案 0 :(得分:4)
setTimeout让我的doSubmitSuccessOperations()在后台运行吗?
没有。 JS是单线程的。代码和呈现在同一个线程中。这就是长时间运行阻止渲染的原因。
setTimeout
做什么预留该操作直到引擎可以执行它(它不会停止运行代码)并且在延迟之后至少(并非完全)指定。正常执行后的代码,就好像它是线程中的下一个操作一样。这意味着setTimeout
中的代码与代码中显示的代码的顺序不同。
我清楚地感觉到doSubmitSuccessOperations()阻止了UI操作,JS中是否存在UI线程和后台线程的概念?
上面的setTimeout还有其他替代方案吗?
异步编程是一个,定时器(setTimeout
和朋友)是最常用的。在其他环境中,IE有setImmediate
,Node有process.nextTick
。还有WebWorkers,它们更接近真正的线程。如果你有一台服务器,你可以使用AJAX(这也是一种异步操作的形式)来调用服务器并让它为你做操作。
Here's a video that explains how the event loop works。视频中间某处解释了how setTimeout
schedules your callbacks。
答案 1 :(得分:3)
基本上,您有一个在浏览器中运行代码的JavaScript引擎。这个引擎有一个调用堆栈。它是您排队等待执行的所有函数的堆栈。还有一个叫做事件循环的东西,它是一个包含在那里排队的函数的队列,作为某个事件的副作用。当调用堆栈为空时,放在事件循环顶部的函数将被推入调用堆栈并执行。此调用堆栈位于UI线程的“内部”。
当你调用setTimeout(doSubmitSuccessOperations,1000)时;在执行此代码行后1秒,将doSubmitSuccessOperations添加到事件循环中。当您执行所有UI逻辑(显示微调器,移动文本,动画等)时,调用堆栈将为空。然后doSubmitSuccessOperations将从事件循环中弹出并推送到调用堆栈中。这是函数执行的时候。
所以,不,setTimeout不会使doSubmitSuccessOperations在后台运行。它只是让它在UI逻辑之后运行。
后台线程有一个概念,它叫做服务工作者。但你不能在其中进行UI操作。
答案 2 :(得分:2)
1)setTimeout让我的doSubmitSuccessOperations()在后台运行吗? - 没有
2)我清楚地感觉到doSubmitSuccessOperations()阻止了UI操作,JS中是否存在UI线程和后台线程的概念? - 没有
3)上面的setTimeout还有其他选择吗? - 您可以尝试在超时时加0,这样引擎会尝试在第一个可用位置执行该功能。
答案 3 :(得分:0)
您在第三个查询的其他答案中解释了所有查询,您可以使用回调模式显示加载图像,它可以运行您可以尝试 而不是这个
function submitSuccesscallback(){
showLoadingIndicator(); // has code a display loader
doSubmitSuccessOperations();// has code to do some app specific operations
}
类似
submitSuccesscallback(function(){
showLoadingIndicator(function(){
doSubmitSuccessOperations()
})
})
你的另一个函数必须处理类似
的回调function showLoadingIndicator(callback){
// your code to display loading image
$('loadingimage').show(0,'', function(){
callback();
});
}
function submitSuccesscallback(callback){
// your code must be sync here
// if asynchrony than call callback in .success function
//at last(if no asyn operation)
callback()
}