Node.js承诺Q.all无效

时间:2014-03-04 01:19:30

标签: javascript node.js promise q

我有这个readLines函数来逐行解析:

var fs = require('fs');
var Q = require('q');

Q.all(readLines(fs.createReadStream("/tmp/test.txt"), console.log)).then(function () {
    console.log('Done');
};

function readLines(input, func) {
    var remaining = '';

    input.on('data', function (data) {
        remaining += data;
        var index = remaining.indexOf('\n');
        while (index > -1) {
            var line = remaining.substring(0, index);
            remaining = remaining.substring(index + 1);
            func(line);
            index = remaining.indexOf('\n');
        }
    });

    input.on('end', function () {
        if (remaining.length > 0) {
            func(remaining);
        }
    });
};

有人可以帮忙,为什么我从来没有“完成”?任何教程都能理解Promises的工作原理吗?

1 个答案:

答案 0 :(得分:1)

这对你来说会更好。请阅读代码中的注释 - 它实际上只有几行,这包括添加错误处理。

var fs = require('fs');
var Q = require('q');

// you don't need Q.all unless you are looking for it to resolve multiple promises.
// Since readlines returns a promise (a thenable), you can just then() it.
readLines(fs.createReadStream("./vow.js"), console.log).then(function (x) {
    console.log('Done',  x);
});

function readLines(input, func) {
    // you need to create your own deferred in this case - use Q.defer()
    var deferred = Q.defer();
    var remaining = '';

    input.on('data', function(data) {
        remaining += data;
        var index = remaining.indexOf('\n');
        while (index > -1) {
            var line = remaining.substring(0, index);
            remaining = remaining.substring(index + 1);
            func(line); 
            index = remaining.indexOf('\n');
        }
    });

    input.on('end', function() {
        if (remaining.length > 0) {
            func(remaining);
            console.log('done');
        }
        // since you're done, you would resolve the promise, passing back the 
        // thing that would be passed to the next part of the chain, e.g. .then()
        deferred.resolve("Wouldn't you want to return something to 'then' with?");
    });

    input.on('error', function() {
        console.log('bother');
        // if you have an error, you reject - passing an error that could be
        // be caught by .catch() or .fail()
        deferred.reject(new Error('Regrettable news - an error occured.'));
    });
    // you return the promise from the deferred - not the deferred itself
    return deferred.promise;
};