Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/463.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么这个使用承诺的异步IO会生成一个零长度的文件?_Javascript_Node.js_Raspberry Pi_Promise_Bluebird - Fatal编程技术网

Javascript 为什么这个使用承诺的异步IO会生成一个零长度的文件?

Javascript 为什么这个使用承诺的异步IO会生成一个零长度的文件?,javascript,node.js,raspberry-pi,promise,bluebird,Javascript,Node.js,Raspberry Pi,Promise,Bluebird,有人能找出这个代码的错误吗?我试图将少量字节写入一个文件,得到的只是一个零长度的文件,没有错误报告 我正在尝试使用node.js中的异步文件IO和bluebird promises将一些数据写入本地文件。我已经成功地编写了这个函数的同步版本和使用回调的异步版本。但是,因为回调版本是嵌套的,有各种各样的错误处理问题,并且不太容易维护,所以我想我应该尝试使用Promissions版本,因为这应该是它的优点(更好的错误处理,更少的嵌套,更容易对异步操作排序) 不幸的是,promise版本只会产生一个长

有人能找出这个代码的错误吗?我试图将少量字节写入一个文件,得到的只是一个零长度的文件,没有错误报告

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

不幸的是,promise版本只会产生一个长度为零的文件。以下是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()
错误消息将按所需顺序显示。我已经验证了所有返回值和参数。没有以任何方式报告错误。在再次运行之前,我已删除了上一个文件。我在回调版本中使用了相同的参数和文件名,效果很好(这似乎排除了文件权限问题)。我重新启动了电脑(顺便说一句,这是一个树莓圆周率)


我被难住了。我想这一定是愚蠢的,我在使用承诺时做错了,但我一辈子都看不出有什么不对。

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

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

这个特定的函数传递了一个参数,用于确定编写是需要同步还是异步(正是出于这个原因),而我还没有编写新promise样式代码的同步部分(我已经编写了我使用过的代码的其他版本的同步版本)

奇怪的谜团解开了。而且,这是一件愚蠢的事情。与承诺没有直接关系,但这是一个异步问题


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

+1使用bluebird:)这对我来说很有效。你能让它更具可复制性吗?@simonzack-我必须看看我是否能在独立的node.js应用程序中复制它。@simonzack-Hmmm。它在同一平台上的独立的node.js应用程序中工作。好的,显然代码在结构上没有问题。现在,我想知道应用程序的上下文是什么导致了问题?此代码似乎不依赖于任何其他内容。唯一传入的数据是创建的文件名,这样就不是垃圾了。我已经注释掉了这个函数中的所有其他代码,没有任何更改。我没有看到任何意外的全局变量(也在严格模式下运行)。这很奇怪。有什么其他的想法吗?很有趣。如果使用setTimout强制将文件写入另一个事件线程,回调版本会发生什么?超时延迟的长度是否重要?对于这项运动,您是否愿意运行蓝鸟的Zalgo构建,看看它是否表现出与回调相同的行为?承诺提供异步性保证,回调不会,但Zalgo构建会删除它们。(此外,这里要做的适当事情可能是阻止并使用同步版本的函数,因为它位于应用程序出口处理程序上)@BenjaminGruenbaum-我如何在我的Raspeberry Pi上运行Zalgo构建?是的,我最终必须编写此保存功能的异步和同步版本,以便在应用程序退出时使用同步版本,在正常应用程序操作期间使用异步版本。有点痛苦,但我不知道有什么其他方法可以解决我的问题,除非我一直使用同步版本,我真的不想这么做。这听起来。。。令人沮丧的。我会看看是否能想出一个聪明的方法,只写一次代码。你可以控制关闭你的应用程序吗?