NodeJS同步功能

时间:2014-12-17 07:43:02

标签: javascript node.js undefined promise sync

我有一个文本文件,只列出了一些URL。我正在尝试从文本文件中获取每一行,并将其添加到url数组以进行进一步操作。

var fs = require('fs'),
    Urls = [];

var returnURLS = function(file) {

    var read = function(callback) {
        fs.readFile(file, function(err, logData){
            if (err) throw err;
            var text = logData.toString();
            var lines = text.split('\n');
            lines.forEach(function(line, callback){
                var url = "http://www." + line;
                Urls.push(url);
            });
            callback();
        });
    };

    var giveBackAnswer = function() {
        console.log("1: ", Urls);
        return Urls;     
    };

    read(giveBackAnswer);

};

console.log("2: ", returnURLS('textFileWithListOfURLs.txt'));

我的控制台输出清楚地表明,在程序记录结果时文件系统操作尚未完成,但结果最终会显示出来。

2: the urls are  undefined
1:  [ 'http://www.cshellsmassage.com',
  'http://www.darsanamartialarts.com',
  'http://www.davidgoldbergdc.com',
  'http://www.dayspaofbroward.com',.... (etc)

让这些功能同步运行的最佳方法是什么? 1)通过文件系统操作编译Urls数组 2)填充后将阵列打印到控制台

3 个答案:

答案 0 :(得分:1)

好吧,你的函数返回undefined。这是因为JavaScript中的所有函数都返回undefined

如果你想使用回调挂钩你的函数,它必须自己进行回调,然后你将继续放在回调中:

var returnURLS = function(file, whenDone) {

    var read = function(callback) {
        fs.readFile(file, function(err, logData){
            if (err) whenDone(err);
            var text = logData.toString();
            var lines = text.split('\n');
            lines.forEach(function(line, callback){
                var url = "http://www." + line;
                Urls.push(url);
            });
            callback();
        });
    };

    var giveBackAnswer = function() {
        console.log("1: ", Urls);
        whenDone(null, Urls);
    };

    read(giveBackAnswer);

};

可以让你这样做:

returnURLS("textFileWithList.txt", function(err, list){
    console.log("2: ", list);
});

使用promises(bluebird)的替代解决方案看起来像:

var fs = Promise.promisify(require("fs"));
var returnURLS = function(file) {
    return fs.readFileAsync(file).then(function(logData){
        var text = logData.toString();
        var lines = text.split('\n');
        return lines.map(function(line){
            return "http://www." + line;
        });
    });
};

可以让你这样做:

returnURLS("url.txt").then(function(data){
       console.log("Got data!", data);
});

答案 1 :(得分:1)

您可以在这个简单的案例中使用fs.readFileSync

var returnURLS = function(file) {
    var text = fs.readFileSync(file).toString();
    var lines = text.split('\n');
    lines.forEach(function(line, callback){
        var url = "http://www." + line;
        Urls.push(url);
    });
    return Urls;     
};

当你不需要并行时,这就完全可以了,就像在这个小型实用程序中一样。

但是你在其他地方重新应用的解决方案是完全异步,不返回结果,而是将其作为参数传递给回调:

var fetchURLS = function(callback) {

        fs.readFile(file, function(err, logData){
            if (err) throw err;
            var text = logData.toString();
            var lines = text.split('\n');
            lines.forEach(function(line, callback){
                var url = "http://www." + line;
                Urls.push(url);
            });
            callback(Urls);
        });
    };
};

fetchURLS('textFileWithListOfURLs.txt', function(urls){
     console.log("2: ", urls);
});

当您的代码变得复杂时,use promises可以方便地减少"回调地狱"。

答案 2 :(得分:0)

使用回调包裹该功能

var fs = require('fs'),
    Urls = [];

function doit(cb){

var returnURLS = function(file) {

    var read = function(callback) {
        fs.readFile(file, function(err, logData){
            if (err) throw err;
            var text = logData.toString();
            var lines = text.split('\n');
            lines.forEach(function(line, callback){
                var url = "http://www." + line;
                Urls.push(url);
            });
            callback();
        });
    };

    var giveBackAnswer = function() {
        console.log("1: ", Urls);
        return Urls;     
    };

    read(giveBackAnswer);

};

cb(returnURLS);

}


doit(function(result){
console.log("2: ", result('textFileWithListOfURLs.txt'));
});