gpt4 book ai didi

Node.js Redis 异步问题

转载 作者:可可西里 更新时间:2023-11-01 11:05:15 26 4
gpt4 key购买 nike

我来自 PHP 背景,试图围绕“事件驱动”的 Node.js 环境进行思考。我写了一个小脚本,它从目录中读取文件并用节目的标题、季节和剧集编号更新 Redis(如果它们晚于当前存储在数据库中的内容)。看来我遇到了一个异步问题,我无法完全理解 Redis DB 标题为“我的节目”、第“05 季”和标题“01”的地方。正在读取两个文件,其中包含“My Show S05E02”和“My Show S05E01”。

数据库应该只在季节/剧集晚于当前季节/剧集时更新,但是由于“updateTitle”被调用得非常快,并且出于某种原因“My Show S05E02”在“My Show S05E01”之前传递update 函数总是将两个值与原始值“My Show S05E01”进行比较,因此它用 E02 更新 Redis,然后再次更新 E01!

代码如下:

function processFiles()
{
fs.readdir(WATCH_DIR, function(err, files){
for (var i = 0; i <= files.length; i++)
{
checkFile(files[i]);
}
});
}

function updateTitle(title, season, episode)
{
var cur_season, cur_episode;

redis_client.hget(title, 'Season', function(err, data){
cur_season = data;
redis_client.hget(title, 'Episode', function(err, data){
cur_episode = data;
redis_client.sismember('Titles', title, function(err, data){
console.log('comparing S'+season+'E'+episode+' to current S'+cur_season+'E'+cur_episode);
if ((season == cur_season && episode >= cur_episode) || season > cur_season)
{
redis_client.hset(title, 'Season', season);
redis_client.hset(title, 'Episode', episode);
console.log('setting '+title+' S'+season+'E'+episode);
}
});
});
});
}

function checkFile(file, mtime)
{
var reg = new RegExp("^"+FILE_PREFIX);
var seasoned = new RegExp("S(\\d{2})E(\\d{2})", "i");

var cache = {}
if (reg.test(file))
{
fs.stat(WATCH_DIR + file, function(err, stats){
console.log(file, stats.mtime.toLocaleDateString() +' '+ stats.mtime.toLocaleTimeString() );
fs.readFile(WATCH_DIR + file, 'utf8', function(ferr, data){
if (seasoned.test(data))
{
title = data.replace(/S(\d{2})E(\d{2})(.*?)$/, '')
.replace(/[\._\-]+/, ' ')
.replace(/^\s+/, '')
.replace(/\s+$/, '');

var season = data.match(/S(\d{2})/i);
season = season[1];
var episode = data.match(/E(\d{2})/i);
episode = episode[1];
updateTitle(title, season, episode);
}
});
});
}
}

fs.watch(WATCH_DIR, function(type, file){
if (type == 'change')
{
processFiles();
}
});

如有任何帮助,我们将不胜感激。我确定这里还有其他错误或最佳实践,也请随时分享这些错误 - 但我只是在用头撞墙试图找出异步问题!

仅供引用 - 这只是一个宠物项目,因此我可以记住我喜欢看的每一集我目前正在观看的每一集。

最佳答案

问题是您在这里无法保证执行顺序。例如,它可能按以下顺序发生:

  1. 阅读文件 1
  2. 首先向Redis发出get请求
  3. 阅读文件 2
  4. 向Redis发起第二次get请求
  5. 首先从 Redis 获取返回值。
  6. 第二次从 Redis 获取返回。
  7. 首先执行设置到 Redis。
  8. 对 Redis 执行第二组操作。

如果第一个操作取决于第二个操作的结果,您需要确保第一个操作在开始第二个操作之前完成,这通常使用回调来完成。

考虑一下:

function doSomethingAsync (num) {
console.log('Starting something ' + num);
setTimeout(function () {
console.log('Done doing something ' + num);
}, 10);
}

function runEverything () {
for (var i = 0; i < 3; i++)
doSomethingAsync(i);
}

runEverything();

哪些输出:

Starting something 0
Starting something 1
Starting something 2
Done doing something 0
Done doing something 1
Done doing something 2

但是,如果我们添加一个回调结构并替换 runEverything 中的循环来使用这些回调,那么它会等待前面的 doSomethingAsync 在它之前完成开始执行下一个:

function doSomethingAsync (num, callback) {
console.log('Starting something ' + num);
setTimeout(function () {
console.log('Done doing something ' + num);
callback();
}, 10);
}

function runEverything () {
var i = 0;
var doneCallback = function () {
if (++i < 3)
doSomethingAsync(i, doneCallback);
};

doSomethingAsync(i, doneCallback);
}

哪些输出:

Starting something 0
Done doing something 0
Starting something 1
Done doing something 1
Starting something 2
Done doing something 2

欢迎使用 Node.js。

关于Node.js Redis 异步问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15792235/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com