[英]IO writing in node-js
我有一个node.js(语法实际上是Typescript)应用程序:
非阻塞事件循环循环对我来说不是很清楚(如果我没弄错的话, 它不是幕后的单线程 ),而且我担心cron模块在写入文件时会重置文件的情况。
我需要担心吗? 就像在我承诺的fs.writeFile
正在写入时设置的全局标志一样? 有没有更优雅的处理方式?
感谢和抱歉,如果这是一个愚蠢的问题。
这是我的代码的骨架:
import * as fs from 'fs';
import * as path from 'path';
import { CronJob } from 'cron';
import { pfs } from './promisifiedFs';
const daily_file = '/path_to_my_file'
new CronJob('0 0 * * * *', function() {
fs.writeFileSync(daily_file, 0, {'flag': 'w'});
}, null, true);
// somewhere called inside an HTTP GET handler
async function doBill(data) {
const something = //....
const currentCountRaw = await pfs.readfilePromisified(daily_file, 'utf-8');
const currentCount = parseFloat(currentCountRaw) || 0;
await pfs.writeFilePromisified(daily_file, currentCount + something, {'flag': 'w'});
}
在Node.js中, 您的代码在单个线程中运行。 它是单线程的,除非您正在使用执行异步I / O的本机模块,而这些模块恰好将工作负载卸载到线程池中(并非总是如此), 或者如果您使用集群模块。
当您在脚本中使用writeFileSync时,主线程将一直阻塞,直到您完成该操作为止,并且不会并行执行其他任何操作。
编辑:如注释中所述,有可能发生以下情况:cron作业在读取和写入之间运行。 还有另一种情况不太可能发生,但有可能发生:异步写入已在运行,并且cronjob运行。 因此,我恢复了我的说法,因为它是错误的,建议您创建一个互斥体,如变量或锁定文件。
我建议使用异步队列 (如果您仅运行节点应用程序的一个实例)或锁文件 (如果您打算集群或使用多个进程)之类的东西。
下面是一些代码(我相信)将复制我所上述,这个问题通过写这应该增加多写碰撞的机会更大价值。
我的计算机似乎要执行的操作是fs.writeFileSync
然后…什么都不做? 我可能会误会,但这是我正在使用的代码。 我选择使用co
而不是async/await
来避免进行转换。
const fs = require('fs');
const co = require('co');
const crypto = require('crypto');
function wait(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
function now() {
return new Date().toISOString();
}
function log(...args) {
return console.log(now(), ...args);
}
const file = './output.txt';
log('generating bytes...');
const bytes = crypto.randomBytes(100000000);
log('done generating bytes');
function writeAsync() {
return new Promise((resolve, reject) => {
return fs.writeFile(file, bytes.toString('base64'), { 'flag': 'w' }, err => {
if (err) {
return reject(err);
}
return resolve();
});
});
}
function writeSync() {
fs.writeFileSync(file, 'FINDMEFINDMEFINDME', { 'flag': 'w' });
}
function run() {
return co(function*() {
log('before write async');
const promise = writeAsync().then(() => log('after write async'));
const ms = 1;
log(`waiting for ${ms} ms`);
yield wait(ms);
log('done waiting');
log('before write sync');
writeSync();
log('after write sync');
yield promise;
});
}
run().catch(err => console.error(err));
输出示例:
2016-10-03T22:52:05.032Z generating bytes...
2016-10-03T22:52:06.846Z done generating bytes
2016-10-03T22:52:06.848Z before write async
2016-10-03T22:52:06.999Z waiting for 1 ms
2016-10-03T22:52:07.001Z done waiting
2016-10-03T22:52:07.001Z before write sync
2016-10-03T22:52:07.012Z after write sync
2016-10-03T22:52:08.623Z after write async
行为:
似乎文件输出包含writeAsync()
的结果,而writeSync()
对输出没有影响。 老实说,我有点希望抛出一个错误。 甚至writeSync()
将'FINDMEFINDMEFINDME'
放置在其他代码的中间,但是我无法在输出文件中找到该字符串。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.