异步实际上是如何在引擎盖下工作的?

den*_*hoe 8 javascript multithreading operating-system asynchronous objective-c-blocks

我一直在以同步和异步的方式研究很多多线程,回调,调度队列...我研究的越多,我就越感到困惑和沮丧,我觉得我似乎无法理解它..请有人可以引导我向正确的方向开始..到目前为止我发现的大部分信息都是关于什么是有用的和有利的东西..我真正希望知道的是当函数与回调异步时该函数如何立即返回并在一个线程上.[这里]的(http://nathansjslessons.appspot.com/lesson?id=1085)我从中得到了这些信息

The function **returns immediately** before the file is read and schedules the read to happen       
sometime in the future. Once the data is ready, the callback function is called on the    
data.
Run Code Online (Sandbox Code Playgroud)

下面是一个如何使用常规阻塞读取函数来获取文件内容的示例 var readFile = function(){

var data;
data = read('file.txt');
dosomething('contect' + data);
}
Run Code Online (Sandbox Code Playgroud)

这是使用异步readAsync函数的相同示例.

var readFileAsynch = function () {
     var func = function (x) {
          // i can do something with data
         dosomthing('content'+data);
     }
     **readAsynch('file.txt',func);** 
      dosomemorestuff();
     };
Run Code Online (Sandbox Code Playgroud)

从我所知道的是,如果你使用另一个线程而不是主线程比我认为这是异步的方式那么如果你只有一个像javascript的线程那么异步真的会如何工作..?

并且,当涉及到目标c中的调度队列时,认为队列是指向块或函数的指针的正确数组并且线程负责在应用程序中管理此队列是正确的吗?

我真的很抱歉,我的问题非常模糊,但我也是...希望任何能提供一些源代码或实现的人都可以阅读,以了解真正发生的事情.我厌倦了阅读"使用线程非常昂贵"之类的东西......但是以什么方式......?或者,我不需要了解它..?

编辑:那么readAsynch('file.txt',func)如何; 行为不同于其他功能,以便它被称为asynch ..?为什么它可以立即执行dosomemorestuff而无需等待readAsynch函数,除非(我认为)当你调用readAsynch时,它是由另一个线程完成的?

小智 6

这一切都取决于我的朋友的实现,如果遵循语言规范,每个浏览器都可以在幕后做任何他们想做的事情。

您不必担心线程和所有其他问题,但如果您担心,请记住这一点:

JavaScript 不是一种“线程”语言,它使用事件循环流,其中触发一个事件,然后触发连续的函数,直到没有更多的东西可以调用。这就是为什么如果您正在编写“好的”代码,则很难在 JavaScript 中阻止 UI。

可以同时调用多个函数而完全不会阻塞,这就是它的美妙之处。函数的每次执行都有自己的生命周期,如果同时触发 3 个事件处理程序,则这 3 个事件处理程序将同时运行,而不是线性执行。

关于其工作原理以及事件循环和经典线程之间的差异的一个很好的例子是 node.js,我将给您一个例子:

假设您正在服务器上侦听请求,请求到达后 2 秒您将发送一条消息。现在假设您复制该侦听器,并且两个侦听器都执行相同的操作。如果您请求服务器,您将在发出请求 2 秒后同时收到两条消息,而不是在 2 秒后收到一条消息,在 4 秒后收到另一条消息。这意味着两个侦听器同时运行,而不是像大多数系统那样遵循线性执行。

异步意味着:你告诉某个服务(DOM、服务器等)执行一个操作,然后附加一个事件处理程序,一旦服务告诉你,我已经得到你想要的,或者我已经做了什么,就会执行该事件处理程序你需要。该处理程序的执行与任何其他鼠标单击或按键的执行相同。事件处理程序的链接可能会很痛苦,但我相信它比阻塞 UI 更好。

我希望您发现这很有用,而不是更令人困惑。


Chr*_*sky 5

在相当多的异步环境中,只有一个线程在处理事情。我们称其为“前景”。需要处理的事情是由某种调度程序安排的。函数指针队列可能构成该调度程序的核心。函数指针与回调几乎相同。

当前台想要做一些耗时的事情时,例如查询数据库或读取文件,那么前台会向底层操作系统或库发出请求,并留下一个回调,以便在完成该耗时的事情时调用。(该处理在另一个线程中进行,可能在另一个进程中进行,或者在内核中进行,这是非常异步的。)请求有某种与之关联的 ID,这样当任务完成时,就会得到正确的回调调用并得到正确的结果。

当该请求正在进行时,前台可以继续执行接下来发生的任何事情。如果一个执行块完成,前台将返回到调度程序。调度程序将从队列中选择下一个任务。其中一项任务是运行一些回调函数,传递正确的数据,以执行一些刚刚完成的缓慢操作。