为什么使用promises的异步IO生成零长度文件?

时间:2014-09-06 03:55:23

标签: javascript node.js raspberry-pi promise bluebird

有人能弄清楚这段代码有什么问题吗?我正在尝试将少量字节写入文件,而我得到的只是一个零长度文件而没有报告错误。

我正在尝试在node.js中使用异步文件IO和bluebird promises将一些数据写入本地文件。我已成功编写了此函数的同步版本和使用回调的异步版本。但是,因为回调版本是嵌套的地狱并且有各种各样的错误处理问题并且不容易维护,我想我会尝试使用promises的版本,因为这应该是它的强项(更好的错误处理,更少的嵌套,更容易对异步操作进行排序)。

不幸的是,promise版本只会产生一个零长度的文件。这是承诺版本的代码:

// at initialization time
var Promise = require('bluebird');
var fs = Promise.promisifyAll(require('fs'));


    // code in a function
    var header = new Buffer('[temperatures] {"formatVersion": "1", "fields": ["t", "atticTemp", "outsideTemp"]}\r\n');
    filename += ".new";
    console.log("async write started");
    var fd;
    fs.openAsync(filename, "w", 438).then(function(ffd) {
        fd = ffd;
        return fs.writeAsync(fd, header, 0, header.length, null);            
    }).then(function(args /* [written, buffer] */) {
        var written = args[0];
        console.log("bytes written =" + written);
        if (written !== header.length) {
            console.log("not all data written");
            throw new Error("not all data written");
        }

        // lots more data to write here

        return fs.closeAsync(fd);
    }).then(function() {
        fd = null;
        console.log(" async write finished");
    }).catch(function(e) {
        // if (fd) fs.closeAsync(fd);
        console.log(e, "data.writeData() - error writing data (new format)");
    });

我已经做了我知道如何进行调试的所有事情。所有预期的console.log()错误消息都以所需顺序显示。我已经验证了所有返回值和参数。不以任何方式报告错误。我再次运行之前删除了以前的文件。我在我的回调版本中使用相同的参数和文件名工作正常(这似乎排除了文件权限问题)。我重新启动了计算机(顺便说一句,这是一个Raspberry Pi)。

我很难过。我认为这一定是愚蠢的我在使用承诺时做错了,但我不能为我的生活看到错误。

1 个答案:

答案 0 :(得分:0)

好的,我明白了。在应用程序的正常操作中调用此函数时,此函数完全正常。而且,如果我在应用程序仍在运行时查看它生成的文件,那么文件就可以了。

但是(这就是出现问题的地方),我也会在应用程序退出时调用此函数。而且,猜猜看,你可以在退出事件处理程序中使用这些类型的异步操作而不会导致问题。它可以创建新的空文件然后退出应用程序以及剩下的东西(只是磁盘上新创建的空文件)。

这个特殊的函数有一个参数传入,因为写入是否需要同步或异步(仅仅是因为这个原因)而且我还没有编写新的promise样式代码的同步部分(我已经写过了)我用过的其他代码版本的同步版本。)

奇怪的神秘解决了。而且,这是愚蠢的事情。没有什么与promises直接相关,但这是一个异步问题。

另一个谜团是为什么我的代码版本是异步的,但使用回调而不是promises没有显示这个问题?显然,它在流程退出之前完成了它的工作,但承诺版本没有。