Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使Node.JS异步_Javascript_Node.js_Asynchronous - Fatal编程技术网

Javascript 如何使Node.JS异步

Javascript 如何使Node.JS异步,javascript,node.js,asynchronous,Javascript,Node.js,Asynchronous,我正在努力思考如何克服和处理Node.JS的异步特性。我对它做了大量的阅读,并试图通过使用消息传递解决方案或回调函数使Node做我想做的事情 我的问题是我有一个对象,我想在其中使用构造函数加载文件并填充数组。然后我希望对这个函数的所有调用都使用加载的数据。因此,我需要原始调用等待文件加载,所有后续调用使用已加载的私有成员 我的问题是,加载数据并获取数据的函数是异步执行的,即使它返回带有回调的函数也是如此 不管怎样,有什么简单的东西我错过了吗?或者这里有没有更简单的模式?此函数应返回加载文件的一部

我正在努力思考如何克服和处理Node.JS的异步特性。我对它做了大量的阅读,并试图通过使用消息传递解决方案或回调函数使Node做我想做的事情

我的问题是我有一个对象,我想在其中使用构造函数加载文件并填充数组。然后我希望对这个函数的所有调用都使用加载的数据。因此,我需要原始调用等待文件加载,所有后续调用使用已加载的私有成员

我的问题是,加载数据并获取数据的函数是异步执行的,即使它返回带有回调的函数也是如此

不管怎样,有什么简单的东西我错过了吗?或者这里有没有更简单的模式?此函数应返回加载文件的一部分,但返回未定义的文件。我已经检查了文件是否确实正在加载,并且工作正常

函数歌(){
这节经文=未定义;
this.loadVerses=函数(verseNum,回调){
如果(this.verses==未定义){
var fs=require('fs'),
文件名='README.md';
fs.readFile(文件名'utf8',函数(错误,数据){
如果(错误){
log('打开文件时出错:%s,错误:%s',文件名,错误];
犯错误;
}否则{
这是数据;
返回回调(verseNum);
}
});
}否则{
返回回调(verseNum);
}
}
this.getVerse=函数(verseNum){
返回这个。第[verseNum+1]节;
}
}
Song.prototype={
诗句:功能(输入){
返回this.loadVerses(输入,this.getVerse);
}
}
module.exports=新歌曲();
更新: 这就是我如何使用另一个模块的歌曲模块

var song = require('./song');
return song.verse(1);
“我的问题是,加载数据并获取数据的函数正在异步执行,即使它返回带有回调的函数。”

@AlbertoZaccagni我所说的场景是,这行
返回this.loadVerses(输入,this.getVerse)在加载文件之前返回

这就是node的工作原理,我将尝试用一个例子来说明它

function readFile(path, callback) {
  console.log('about to read...');
  fs.readFile(path, 'utf8', function(err, data) {
    callback();
  });
}

console.log('start');
readFile('/path/to/the/file', function() {
  console.log('...read!');
});
console.log('end');
您正在读取一个文件,并且在控制台中可能有

  • 开始
  • 即将阅读
  • 结束
  • …读
您可以单独尝试以查看它的实际效果,并对其进行调整以了解要点。这里需要注意的是,您的代码将继续运行,跳过回调的执行,直到读取文件为止

声明回调并不意味着执行将停止,直到调用回调然后恢复

这就是我将如何更改代码:

function Song() {
  this.verses = undefined;

  this.loadVerses = function(verseNum, callback) {
    if (this.verses === undefined) {
      var fs = require('fs'),
      filename = 'README.md';
      fs.readFile(filename, 'utf8', function(err, data) {
        if (err) {
          console.log('error throw opening file: %s, err: %s', filename, err);
          throw err;
        } else {
          this.verses = data;
          return callback(verseNum);
        }
      });
    } else {
      return callback(verseNum);
    }
  }
}

Song.prototype = {
  verse: function(input, callback) {
    // I've removed returns here
    // I think they were confusing you, feel free to add them back in
    // but they are not actually returning your value, which is instead an
    // argument of the callback function
    this.loadVerses(input, function(verseNum) {
      callback(this.verses[verseNum + 1]);
    });
  }
}

module.exports = new Song();
要使用它:

var song = require('./song');
song.verse(1, function(verse) {
  console.log(verse);
});
我忽略了

  • 我们没有将错误作为回调的第一个参数
  • 事实上,要求速度足够快将创造比赛条件,但我相信这是另一个问题
  • “我的问题是,加载数据并获取数据的函数正在异步执行,即使它返回带有回调的函数。”

    @AlbertoZaccagni我所说的场景是,这行
    返回this.loadVerses(输入,this.getVerse)在加载文件之前返回

    这就是node的工作原理,我将尝试用一个例子来说明它

    function readFile(path, callback) {
      console.log('about to read...');
      fs.readFile(path, 'utf8', function(err, data) {
        callback();
      });
    }
    
    console.log('start');
    readFile('/path/to/the/file', function() {
      console.log('...read!');
    });
    console.log('end');
    
    您正在读取一个文件,并且在控制台中可能有

    • 开始
    • 即将阅读
    • 结束
    • …读
    您可以单独尝试以查看它的实际效果,并对其进行调整以了解要点。这里需要注意的是,您的代码将继续运行,跳过回调的执行,直到读取文件为止

    声明回调并不意味着执行将停止,直到调用回调然后恢复

    这就是我将如何更改代码:

    function Song() {
      this.verses = undefined;
    
      this.loadVerses = function(verseNum, callback) {
        if (this.verses === undefined) {
          var fs = require('fs'),
          filename = 'README.md';
          fs.readFile(filename, 'utf8', function(err, data) {
            if (err) {
              console.log('error throw opening file: %s, err: %s', filename, err);
              throw err;
            } else {
              this.verses = data;
              return callback(verseNum);
            }
          });
        } else {
          return callback(verseNum);
        }
      }
    }
    
    Song.prototype = {
      verse: function(input, callback) {
        // I've removed returns here
        // I think they were confusing you, feel free to add them back in
        // but they are not actually returning your value, which is instead an
        // argument of the callback function
        this.loadVerses(input, function(verseNum) {
          callback(this.verses[verseNum + 1]);
        });
      }
    }
    
    module.exports = new Song();
    
    要使用它:

    var song = require('./song');
    song.verse(1, function(verse) {
      console.log(verse);
    });
    
    我忽略了

  • 我们没有将错误作为回调的第一个参数
  • 事实上,要求速度足够快将创造比赛条件,但我相信这是另一个问题
  • [收集到答案中,并根据我以前的评论进行了扩展]

    TL;DR您需要对代码进行结构化,以便任何操作的结果只在该操作的回调中使用,因为您在其他任何地方都无权访问它

    虽然将其分配给外部全局变量肯定会按预期工作,但这样做只会在启动回调后发生,而回调发生在您无法预测的时间

    评论

    回调不会返回值,因为从本质上讲,回调是在将来的某个时候执行的

    将回调函数传递给控制异步函数后,将在周围函数决定调用它时执行它。您无法控制此操作,因此等待返回的结果将不起作用

    您的示例代码,
    song.verse(1)
    不能返回任何有用的内容,因为它会立即被调用,而且由于回调尚未启动,它只会返回它能返回的唯一值:
    null

    我担心这种对带有已传递回调的异步函数的依赖是NodeJS运行方式的一个不可改变的特性;这是它的核心

    不过不要灰心。对所有NodeJS问题的快速调查清楚地表明,只有在回调中才能处理异步操作的结果,这是理解如何在NodeJS中编程的最大障碍

    有关正确构造的各种方法的非常优秀的解释/教程