Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/367.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 节点js-从回调中获取结果_Javascript_Node.js_Asynchronous_Callback - Fatal编程技术网

Javascript 节点js-从回调中获取结果

Javascript 节点js-从回调中获取结果,javascript,node.js,asynchronous,callback,Javascript,Node.js,Asynchronous,Callback,以下是我的节点js代码: var ResponseData = { str: "" }; function GetFilesList( FolderName, ResponseData ) { fs.readdir( FolderName, GetFilesList_callback ); } function GetFilesList_callback( Err, Files ) { if( Err ) throw Err; for( var Idx in F

以下是我的节点js代码:

var ResponseData = { str: "" };

function GetFilesList( FolderName, ResponseData )
{
    fs.readdir( FolderName, GetFilesList_callback );
}

function GetFilesList_callback( Err, Files )
{   
    if( Err ) throw Err;
    for( var Idx in Files )
    {
        var Entry = "File " + Idx + " =" + Files[ Idx ] + "=";
        ResponseData.str += Entry;
        console.log( Entry );
    }
}
调用getFileList()函数后,ResponseData.str不包含文件名,尽管我在concole中看到了它们

根据这里得到的答案,我修改了以下函数:

function GetFilesList( FolderName, ResponseData )
{
    var prom = new Promise( function( resolve, reject )
             { fs.readdir( FolderName, GetFilesList_callback ) } );
    prom.then( function( Files )
                 {
                    ResponseData.str += "x";
                    console.log( "after_promise" );
                 } )
}
new Promise((resolve, reject) => fs.readdir(foldername, (err, files) => {
    resolve(files)
}).then((files) => {
     //do something with the files
})

不执行“then”部分。奇怪的是,如果我向服务器发出第二个请求(即浏览器中的页面刷新),我看到ResponseData.str具有我期望的文件名(但不是“x”es)。

ResponseData.str
确实包含这些文件,但是在
for
-循环之后,您需要继续在回调中使用代码。

根据您访问ResponseData的时间,您可能会在回调完成之前打印出来

为了避免自己陷入回调地狱和node.js的异步性质,请使用承诺

常见的模式如下:

function GetFilesList( FolderName, ResponseData )
{
    var prom = new Promise( function( resolve, reject )
             { fs.readdir( FolderName, GetFilesList_callback ) } );
    prom.then( function( Files )
                 {
                    ResponseData.str += "x";
                    console.log( "after_promise" );
                 } )
}
new Promise((resolve, reject) => fs.readdir(foldername, (err, files) => {
    resolve(files)
}).then((files) => {
     //do something with the files
})

让我们从您使用异步调用的想法开始

首先,编写外部使用数据的函数是一个非常糟糕的主意,特别是当涉及异步时(更不用说函数处理程序了)

请学习你的异步编码知识。首先,应该让函数只处理传入的变量,而不处理来自外部的变量(没有副作用)。虽然您的小示例最终可能会起作用,但您无法像这样构建良好的代码库

其次,正如其他人所指出的,您可能正在调用GetFileList,然后打印结果。因此,对getFileList的调用启动一个异步操作,然后函数结束(因为它存在)。但这并不意味着它完成了预期的操作,因此在下一行中,您将打印ResponseData,并惊奇地发现它是空的。打印数据后,将执行磁盘操作,然后调用回调,此时数据已填写完毕,您的问题应该是“何时知道”或“如何等待”,直到数据填写完毕。您将同步逻辑与异步逻辑混合在一起,这是完全正确的,而且首先每个人都会遇到这种情况

你不需要承诺来解决这个问题,承诺是首选的方式,但是如果你刚刚开始异步编码,我个人会推荐回调,直到你100%理解它,然后转向承诺

看看这段代码,我添加main是为了帮助您理解流程

const fs = require("fs");

function getFilesList(FolderName, callback) {
  fs.readdir(FolderName, callback);
}

function main(callback) {
  getFilesList(".", function(err, files) {
    if(err) {
      return callback(err);
    }

    const responseData = {str: ""};

    for(const Idx in files) {
      const Entry = "File " + Idx + " =" + files[Idx] + "=";
      responseData.str += Entry;
      console.log(Entry);
    }

    callback(null, responseData);
  });
}

main(function(err, responseData) {
  if(err) {
    console.log("Error:", err);
  } else {
    console.log(responseData);
  }
});

顺便问一下,我猜你主要使用C#对吗?@Patrick Roberts你是对的,我是C#,我现在想为转行做好准备。是什么泄露了我的秘密?:)TitleCase变量名和下一行的大括号,这是visual studio和.NET喜欢的编码风格,而JavaScript开发人员倾向于在同一行使用camelCase变量名(类除外)和大括号。或者只是
util.promisify(fs.readdir)(foldername)。然后(文件=>{…},错误=>{…})
,顺便说一句,它正确地拒绝了错误,而不是让承诺挂起。@Eric Yang我已经修改了函数,正如我在后面的文章编辑中所示。仍然不起作用。你能在JSFIDLE或类似的东西中发布你的完整代码,以便我可以尝试为你修复它吗?问题是我在我的nodejs服务器中使用了这个:http.createServer(OnRequest)。listen(8873);在函数OnRequest(Request,Response)中,我必须同步提供一个答案,因此我必须等待来自异步部分的答案,以便将响应传递给OnRequest函数。这正是它的设计工作方式。您的http请求将等待,直到您返回数据。。。异步地,您不应该同步地提供它们。类似这样:函数OnRequest(req,res){getFilesList(“.”),函数(err,files){if(err){return res.end(“发生错误”);}const responseData={str:”};for(const Idx in files){const Entry=“File”+Idx+“=”+files[Idx]+“=”responseData.str+=Entry;console.log(Entry)}res.end(responseData);//您的成功};}在互联网上快速搜索异步概念让我达到了目的,我希望他们会有所帮助:我想我现在找到了。现在,我的第一个NodeJS“异步”服务器已启动并运行。:)我对自己说,这是一个多么美好的世界……:)太好了。祝你好运,如果你还需要什么,请给我留言。总是乐于帮助nodejs。