setTimeout 与 Javascript 中的正常函数执行

setTimeout vs normal function execution in Javascript

在我的应用程序中,我有一个 submitSuccesscallback 函数,当提交成功时,它会从我自己的 JS 库中触发。 在submitSuccesscallback中,我首先展示一个加载器并进行一些初始化操作。

function submitSuccesscallback(){
  showLoadingIndicator(); // has code a display loader
  doSubmitSuccessOperations();// has code to do some app specific operations
}

这里 doSubmitSuccessOperations() 大约需要 5 秒才能完成。

现在我的问题是上面的代码在我得到 submitSuccesscallback().

后最多 5 秒内不显示加载程序(即 ui 从 showLoadingIndicator() 更改)

如果我像下面这样更改 submitSuccesscallback(),我可以在触发 submitSuccesscallback() 后立即看到加载器。

 function submitSuccesscallback(){
  showLoadingIndicator(); // has code a display loader
  setTimeout(doSubmitSuccessOperations, 1000);
}

现在我想知道的是:

  1. setTimeout 是否使我的 doSubmitSuccessOperations() 运行 处于后台?

  2. 我明显感觉到doSubmitSuccessOperations()阻塞了UI操作,请问JS中有UI线程和后台线程的概念吗?

  3. 以上 setTimeout 还有其他选择吗?

does setTimeout makes my doSubmitSuccessOperations() run in background?

没有。 JS是单线程的。代码渲染在同一个线程中。这就是长运行 操作阻塞渲染的原因。

setTimeout所做的是搁置该操作直到引擎可以执行它(它不会停止运行代码)并且至少(但不完全是)在您指定的延迟之后。它之后的代码正常执行,就好像它是线程中的下一个操作一样。这意味着 setTimeout 中的代码已经与您的代码中出现的顺序不同。

I clearly sense that doSubmitSuccessOperations() is blocking UI operation, is there any concept of UI thread and background thread in JS?

Any other alternative for setTimeout above?

异步编程是其中之一,定时器(setTimeout 和朋友)是最可用的。在其他环境下,IE有setImmediate,Node有process.nextTick。还有更接近真实线程的 WebWorkers。如果你有一个服务器,你可以使用AJAX(这也是一种异步操作的形式)来调用一个服务器,让它为你做操作。

Here's a video that explains how the event loop works. Somewhere in the middle of the video explains how setTimeout schedules your callbacks.

1) setTimeout 是否使我的 doSubmitSuccessOperations() 运行 在后台运行? - 没有

2) 明显感觉到doSubmitSuccessOperations()阻塞了UI操作,请问JS中有UI线程和后台线程的概念吗? - 没有

3) 上面的 setTimeout 还有其他替代方法吗? - 您可以尝试将超时设置为 0,这样引擎将尝试在第一个可用位置执行函数。

基本上,您有一个 JavaScript 引擎在浏览器中 运行 整合您的代码。这个引擎有一个调用栈。它是您排队等待执行的所有函数的堆栈。还有一个叫做事件循环的东西,它是一个队列,其中包含作为某些事件的副作用而在那里排队的函数。当调用堆栈为空时,将放在事件循环顶部的函数压入调用堆栈并执行。此调用堆栈是 "inside" 您的 UI 线程。

当你调用 setTimeout(doSubmitSuccessOperations, 1000); doSubmitSuccessOperations 在执行这行代码 1 秒后被添加到事件循环中。当您的所有 UI 逻辑都被执行(显示微调器、移动文本、动画等)时,调用堆栈将为空。然后 doSubmitSuccessOperations 将从事件循环中弹出并推入调用堆栈。这是函数被执行的时候。

所以,不,setTimeout 不会在后台执行 doSubmitSuccessOperations 运行。它只是按照您的 UI 逻辑使其成为 运行。

有一个后台线程的概念,叫做 service worker。但是你不能在里面做UI操作。

你的所有查询都在你的第三个查询的其他答案中解释了你可以使用回调模式来显示加载图像它会起作用你可以试试 而不是这个

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

  }