繁体   English   中英

异步代码,它如何工作? 承诺和回调

[英]Asynchronous code, how does it work? Promises and callbacks

我试图在网上找到答案,并且做了一部分。 但是我仍然不能完全理解JS如何运行异步代码?

我看到的东西:

JS使我们能够进行异步编程。 这意味着我们可以开始第一个任务,然后在一个正在进行的过程中我们可以开始第二个任务,依此类推。在js可以开始第二个任务之前,应该将它从上一个任务中释放出来。 它可以通过两种方式实现:

  • js自己完成任务(仅应由js处理的代码)
  • js可以启动应由文件系统处理的任务。 在这种情况下,js进行工作,将任务传递到文件系统,然后开始处理其他排队的任务。 释放js并且文件系统返回结果后,js可以继续执行该任务。

因此,我们不能仅通过编写以下代码来达到异步:

function doSth( callback ) {
    let arr = [];

    for ( let i=1e6; i > 0; i-- )
        arr.push( i );

    callback();
}

doSth( console.log.bind( null, 'I am callback' );
console.log( 'just a line' );

由于doSth()仅包含js的工作,它将首先完成,然后仅出现“只是一行”? 所以它不是异步的,对吗? 但是,如果我们将文件系统任务插入循环中,我们将具有异步功能吗?

还有一个问题:诺言真的不同步吗? 它们如何异步(我的意思是,在promise处理时可以处理其他任务),或者promise只是模仿异步代码? *我知道,还有其他的承诺期。

Maby我只是不了解某些基础? 如果您能向我解释,让我更清楚地提出我的问题,我将很高兴。

观看此播放列表,以简要了解异步Javascript。

但是,如果您真的想了解所有细节,请阅读本书。

要回答您的主要问题之一,异步与文件系统无关。 仍然都是Javascript。 引用我推荐的书:

异步是“程序的一部分现在运行,而程序的另一部分稍后运行-从现在到以后,程序将无法主动执行。”

考虑您的代码:

function doSth(callback) {
  let arr = [];
  for (let i=1e6; i > 0; i--){
    arr.push(i);
  }
  callback();
}

doSth(console.log.bind(null, 'I am callback'));
console.log('just a line');

这将输出

我回电

然后

只是一条线

但是,如果您将代码更改为此:

function doSth(callback) {
  let arr = [];
  for (let i=1e6; i > 0; i--){
    arr.push(i);
  }
  setTimeout(callback, 0);
}

doSth(console.log.bind(null, 'I am callback'));
console.log('just a line');

你会得到

只是一条线

然后

我回电

本质上,它与调用回调的函数有关。 无论do循环需要多长时间,“ doSth”都不是异步函数。 但是,在第二个示例中,setTimeout是调用您的回调的函数,而setTimeout是一个异步函数,该异步函数在其余同步代码之后运行,只是因为这是它的预期工作方式。 另一个常见的异步函数将是任何类型的AJAX请求,并且提供给它的回调也将在任何其他同步代码之后被调用。

我认为你是对的。

doSth函数是同步的,它将阻塞主线程,直到完成为止。 您仅提供了回调API,但这并不意味着它将神奇地变为异步。

事实是,除非您使用定义为异步的核心JS函数(例如fs.readFilesetTimeout$.ajax({...}).done ),否则您编写的所有JS代码都是同步的。 没有它们,您将无法创建异步行为,您将不得不使用事件循环从头开始编写自己的JS内核(事实上,我鼓励您使用google并研究javascript event loop是什么,我相信它将阐明许多事物,将使您对核心事物有更好的了解)。 那里的所有第3方库都实现了异步行为,这仅仅是因为它们使用了这些核心功能并用自己的代码包装了它们,从而提供了更优雅,更高级的API。

诺言也是如此。 是的,它们是异步的,但仅当您用异步代码填充它们时才如此。 确实,它们有一些额外的开销,并且不会立即运行代码,但是,如果单个promise仅包含同步代码,则其最终执行将阻塞主线程,直到完成为止。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM