node js - 从回调中获取结果

时间:2018-04-13 19:07:29

标签: 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 Files )
    {
        var Entry = "File " + Idx + " =" + Files[ Idx ] + "=";
        ResponseData.str += Entry;
        console.log( Entry );
    }
}

在调用GetFilesList()函数之后,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" );
                 } )
}

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

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

根据您何时访问ResponseData,您可能会在回调完成之前将其打印出来。

为防止自己陷入回调地狱和node.js的异步性质,请使用promises

常见的模式如下:

new Promise((resolve, reject) => fs.readdir(foldername, (err, files) => {
    resolve(files)
}).then((files) => {
     //do something with the files
})

答案 2 :(得分:0)

让我们从错误使用异步调用的想法开始。

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

请刷你的异步编码知识。你应该首先让你的函数只使用传入的变量,而不是外部的任何东西(没有副作用)。虽然你的小例子最终可能会起作用,但你不能像这样建立一个好的代码库。

其次,正如其他人指出的那样,您可能正在调用GetFilesList然后打印结果。因此,对GetFilesList的调用会启动异步操作,然后函数结束(因为它存在)。但这并不意味着它完成了它打算做的事情,所以在下一行你打印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);
  }
});