JavaScript:异步功能

时间:2016-04-04 12:33:11

标签: javascript asynchronous

我试图了解异步代码的概念,因此我生成了以下代码:

"use strict";
var fs = require("fs");
var buf = new Buffer(1024);

console.log("Global Start");
console.log("+++ Async open - truncate - close: open file2 called");
fs.open("file2.txt", "r+", function (err, fd) {
  console.log(" Global + 1 Start");
  if (err) {
    return console.error(err);
  }
  console.log(" +++ Async file2 opened successfully!");

  // Truncate the opened file.
  console.log(" +++ Async open - truncate - close: truncate file2 called");
  fs.ftruncate(fd, 10, function (err) {
    console.log("       Global + 2 Start");
    if (err) {
      console.log(err);
    }
    console.log("       +++ truncate file2 successfully!");
    console.log("       +++ Async open - truncate - close: read file2 called");
    fs.read(fd, buf, 0, buf.length, 0, function (err, bytes) {
      console.log("         Global + 3 Start");
      if (err) {
        console.log(err);
      }
      // Print only read bytes to avoid junk.
      if (bytes > 0) {
        console.log("           Global + 3 +++ truncate read: '" + buf.slice(0, bytes).toString() + "'");
      }

      // Close the opened file.
      console.log("         Global + 3 +++ truncate - open - close: close file2 called");
      fs.close(fd, function (err) {
        console.log("               Global + 4 Start");
        if (err) {
          console.log(err);
        }
        console.log("               Global + 4 ++++++++++++++++++++ Async open - truncate - close file2 + closed ++++++++++++++++++++");
        console.log("               Global + 4 End");
      });

      console.log("         Global + 3 End");
    });
    console.log("       Global + 2 End");
  });
  console.log(" Global + 1 End");
});
console.log("Global End");

创建了以下输出。

Global Start
+++ Async open - truncate - close: open file2 called
Global End
        Global + 1 Start
        +++ Async file2 opened successfully!
        +++ Async open - truncate - close: truncate file2 called
        Global + 1 End
                Global + 2 Start
                +++ truncate file2 successfully!
                +++ Async open - truncate - close: read file2 called
                Global + 2 End
                        Global + 3 Start
                        Global + 3 +++ truncate read: 'This is a '
                        Global + 3 +++ truncate - open - close: close file2 called
                        Global + 3 End
                                Global + 4 Start
                                Global + 4 ++++++++++++++++++++ Async open - truncate - close file2 + closed ++++++++++++++++++++
                                Global + 4 End

所以这就是我所做的:

  1. 全球范围:" Global Start"
  2. 使用在fs.open完成时执行的回调函数调用fs.open。
  3. fs.open开始工作,而不是等待结果,执行全局级别的下一个任务,即全局结束"。

  4. 现在完成fs.open并调用回调函数。我们进入全球+1范围。

  5. 全球+ 1范围:"全球+ 1开始"

  6. 使用在fs.ftruncate完成时执行的回调函数调用fs.ftruncate

  7. fs.ftruncate开始工作,当它工作时,Global + 1范围内的剩余代码被执行,即" Global + 1 End"。

  8. 当fs.ftruncate完成后,它的回调函数被调用。

  9. Global + 3和Global + 4遵循相同的模式。

    所以我的问题是;

    我对代码中发生的事情的描述是否正确?

    在我看来,异步代码是从最外部括号(全局范围)到最内部括号(全局+4范围)执行的。它不是从最内层到外层(就像在数学中一样)而且它不是从顶线到buttomline(如同步代码)。这是对的吗?

    如果完成Global Scope上的函数并在Global Scope上的其他代码完成之前执行其回调函数,会发生什么。回调是否会等待全局代码完成?

    如果对要处理的不同文件执行相同的代码,输出的结果是否会以不同的顺序进行处理?

1 个答案:

答案 0 :(得分:2)

你对此非常了解。至于你的问题:

  1. "在我看来,异步代码是从最外层的括号(全局范围)执行到最内层的括号"
  2. 异步调用将像任何其他命令一样执行,但不是等待结果,而是执行下面的命令。下一个命令是异步回调之后的直线,除非有某种函数调用。

    1. "回调是否会等待全局代码完成?"
    2. 全局范围变量不会等待异步调用,反之亦然。代码将运行,稍后依赖异步调用内的变量的某些代码可能会也可能不会获得这些变量的更新版本。这取决于异步调用是否按时完成。

      1. "如果对要处理的不同文件执行相同的代码,输出的结果是否会以不同的顺序进行处理?"
      2. 同样,执行代码的顺序取决于异步调用的速度。代码将始终以相同的顺序读取。为了防止击败你的异步调用你会确保所有依赖异步调用的JS进入回调,因为它会等到异步完成。

        我相信我回答了你所有的问题,如果我错过了什么,任何人都会发表评论。