setTimeout与javascript中的正常函数执行

时间:2015-11-17 12:57:10

标签: javascript jquery asynchronous javascript-events javascript-objects

在我的应用程序中,我有一个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的其他选择吗?

4 个答案:

答案 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()

  }