【问题标题】:Using promises with Node.js functions on example在示例中使用带有 Node.js 函数的 Promise
【发布时间】:2014-02-18 22:18:12
【问题描述】:

我开始学习 JavaScript 承诺,但我不明白如何将 Q 函数应用到 Node.js 回调函数。

In similar question 建议使用Q.denodeify(),但它适用于fs.readFile(),不适用于fs.exists()

这是一个简单的函数,它返回目录中的文件列表及其大小:

function openDir(path, callback) {
    path = __dirname + path;
    fs.exists(path, function (exists) {
        if (exists) {
            fs.readdir(path, function (err, files) {
                if (err) {
                    throw err;
                }
                var filesCounter = 0,
                    filesTotal = files.length,
                    result = [];
                files.forEach(function (filename, index) {
                    fs.stat(path + filename, function (err, stats) {
                        if (err) {
                            throw err;
                        }
                        result[index] = {};
                        result[index].name = filename;
                        result[index].size = stats.size;
                        if (++filesCounter === filesTotal) {
                            callback(result);
                        }
                    });
                });
            });
        }
    });
}

http.createServer(function (req, res) {
    openDir('/', function (data) {
        res.writeHead(200, {
            'Content-Type': 'application/json; charset=utf-8'
        });
        res.end(JSON.stringify(data));
    });
}).listen(1337, '127.0.0.1');

如何使用 Promise 编写此代码(使用 Q 或其他库)?

【问题讨论】:

标签: javascript node.js promise q


【解决方案1】:

fs.exists 是一种无用的方法。它不返回节点样式回调,通常可以省略。在您的示例中,您将处理来自fs.readdir 的错误。

fs.exists() 是不合时宜的,仅出于历史原因而存在。 几乎不应该有理由在您自己的代码中使用它。 node docs

这是您使用 Q 重新处理的示例,请注意,我们通过返回承诺而不是统计信息本身来将错误处理推迟给调用者。我包含了一个如何使用 Q.defer 处理 fs.exists 的示例,以展示如何代理非节点样式的回调。

var Q = require('q'); 
var fs = require('fs');
var http = require('http');
var readdir = Q.denodeify(fs.readdir);

function stat(file){
    return Q.nfcall(fs.stat, file)
        .then(function(stats){
            stats.filename = file;
            return stats;
        });
}

function openDir(path) {
    path = __dirname + path;

    return readdir(path)
        .then(function(files) { 
            return files.map(function(file){ 
                return stat(path + file); }); })
        .then(Q.all);
};

// proxy fs.exists to return a promise. Example of Q.defer
function exists(file){
    var deferred = Q.defer();
    fs.exists(file, function(result){
        return result ? deferred.resolve(file) : deferred.reject('invalid file');    
    });
    return deferred.promise;
}

http.createServer(function (req, res) {
    openDir('/').done(
        function (data) {
            res.writeHead(200, {
                'Content-Type': 'application/json; charset=utf-8'});
            res.end(JSON.stringify(data));
        },
        function (err) {
            res.writeHead(500, {
                'Content-Type': 'application/json; charset=utf-8'});
            res.end(JSON.stringify({error: err}));
        });
    }).listen(1337, '127.0.0.1');

【讨论】:

    猜你喜欢
    • 2016-10-03
    • 2018-06-16
    • 1970-01-01
    • 1970-01-01
    • 2017-03-25
    • 1970-01-01
    • 2020-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多