node.js 中的异步混乱
Async confusion in node.js
我在试图理解如何使我的代码在 Node.js 领域异步时遇到了很大的麻烦。请在下面查看我的代码,分为两种。
好的,这是我的第一次尝试 - 我在这里有三个函数。一个处理函数(iim),一个文件复制函数(fse.copy),一个存档函数(da)。
我需要 da 在 iim 之后发生,iim 在 fse.copy 之后发生。
第一种方法导致存档发生,但它是空的,因为 iim 似乎从未发生过。
da(randomString, function(err) {
if (err) {
log.error(err);
} else {
fse.copy(temp_path, new_location + file_name, function(err) {
if (err) {
log.error(err);
} else {
log.info("File saved to " + new_location + file_name);
var sourceImage = new_location + file_name;
log.debug(sourceImage);
log.debug(randomString);
iim(sourceImage, randomString, function(err) {
if (err) {
log.error(err);
}
});
}
});
}
});
下一个块是另一种方法,它导致 da 在 iim 完成之前发生。
fse.copy(temp_path, new_location + file_name, function(err) {
if (err) {
log.error(err);
} else {
log.info("File saved to " + new_location + file_name);
var sourceImage = new_location + file_name;
log.debug(sourceImage);
log.debug(randomString);
iim(sourceImage, randomString, function(err) {
if (err) {
log.error(err);
}
});
da(randomString, function(err) {
if (err) {
log.error(err);
}
});
}
});
因此您可以将 da 放入第二个示例的 iim 回调中(现在不是):
fse.copy(temp_path, new_location + file_name, function(err) {
if (err) {
log.error(err);
} else {
log.info("File saved to " + new_location + file_name);
var sourceImage = new_location + file_name;
log.debug(sourceImage);
log.debug(randomString);
iim(sourceImage, randomString, function(err) {
if (err) {
log.error(err);
return;
}
da(randomString, function(err) {
if (err) {
log.error(err);
}
});
});
}
});
也就是说,回调深度可以通过使用像 async (https://github.com/caolan/async)
这样的库来展平
这是我的建议——在你的问题中,你说你基本上需要 运行 三个串联的函数——对吗? 运行 函数 A,然后是函数 B,最后是 运行 函数 C。
最简单的方法是使用 asyncjs 库。
这是一个例子:
var async = require('async');
async.series([
function a(cb) {
// do stuff
cb();
},
function b(cb) {
// do stuff
cb();
},
function c(cb) {
// do stuff
cb();
},
], function() {
// this will run once all three functions above have finished
});
现在,假设这些函数中的每一个都需要 return 数据到下一个函数。所以想象一下,函数 B 需要从函数 A 到 运行 的输入。你如何做到这一点?使用 async.waterfall!
var async = require('async');
async.waterfall([
function a(cb) {
// do stuff
cb(null, 'value');
},
function b(val, cb) {
// do stuff with val
cb(null, 'woot');
},
function c(val, cb) {
// do stuff with val
cb(null);
},
], function() {
// this will run once all three functions above have finished
});
还不错吧?
希望对您有所帮助!
编辑:这是一个代码块,显示您上面使用 asyncjs 重构的代码:
async.waterfall([
function(cb) {
fse.copy(temp_path, new_location + file_name, function(err) {
if (err) {
log.error(err);
} else {
log.info("File saved to " + new_location + file_name);
var sourceImage = new_location + file_name;
log.debug(sourceImage);
log.debug(randomString);
}
console.log('Finished running fs.copy');
cb(null, sourceImage, randomString);
});
},
function(sourceImage, randomString, cb) {
iim(sourceImage, randomString, function(err) {
if (err) {
log.error(err);
}
console.log('Finished running iim');
cb(null, randomString);
});
},
function(randomString, cb) {
da(randomString, function(err) {
if (err) {
log.error(err);
}
console.log('Finished running da');
cb();
});
}
], function() {
console.log('All done!');
});
我在试图理解如何使我的代码在 Node.js 领域异步时遇到了很大的麻烦。请在下面查看我的代码,分为两种。
好的,这是我的第一次尝试 - 我在这里有三个函数。一个处理函数(iim),一个文件复制函数(fse.copy),一个存档函数(da)。
我需要 da 在 iim 之后发生,iim 在 fse.copy 之后发生。
第一种方法导致存档发生,但它是空的,因为 iim 似乎从未发生过。
da(randomString, function(err) {
if (err) {
log.error(err);
} else {
fse.copy(temp_path, new_location + file_name, function(err) {
if (err) {
log.error(err);
} else {
log.info("File saved to " + new_location + file_name);
var sourceImage = new_location + file_name;
log.debug(sourceImage);
log.debug(randomString);
iim(sourceImage, randomString, function(err) {
if (err) {
log.error(err);
}
});
}
});
}
});
下一个块是另一种方法,它导致 da 在 iim 完成之前发生。
fse.copy(temp_path, new_location + file_name, function(err) {
if (err) {
log.error(err);
} else {
log.info("File saved to " + new_location + file_name);
var sourceImage = new_location + file_name;
log.debug(sourceImage);
log.debug(randomString);
iim(sourceImage, randomString, function(err) {
if (err) {
log.error(err);
}
});
da(randomString, function(err) {
if (err) {
log.error(err);
}
});
}
});
因此您可以将 da 放入第二个示例的 iim 回调中(现在不是):
fse.copy(temp_path, new_location + file_name, function(err) {
if (err) {
log.error(err);
} else {
log.info("File saved to " + new_location + file_name);
var sourceImage = new_location + file_name;
log.debug(sourceImage);
log.debug(randomString);
iim(sourceImage, randomString, function(err) {
if (err) {
log.error(err);
return;
}
da(randomString, function(err) {
if (err) {
log.error(err);
}
});
});
}
});
也就是说,回调深度可以通过使用像 async (https://github.com/caolan/async)
这样的库来展平这是我的建议——在你的问题中,你说你基本上需要 运行 三个串联的函数——对吗? 运行 函数 A,然后是函数 B,最后是 运行 函数 C。
最简单的方法是使用 asyncjs 库。
这是一个例子:
var async = require('async');
async.series([
function a(cb) {
// do stuff
cb();
},
function b(cb) {
// do stuff
cb();
},
function c(cb) {
// do stuff
cb();
},
], function() {
// this will run once all three functions above have finished
});
现在,假设这些函数中的每一个都需要 return 数据到下一个函数。所以想象一下,函数 B 需要从函数 A 到 运行 的输入。你如何做到这一点?使用 async.waterfall!
var async = require('async');
async.waterfall([
function a(cb) {
// do stuff
cb(null, 'value');
},
function b(val, cb) {
// do stuff with val
cb(null, 'woot');
},
function c(val, cb) {
// do stuff with val
cb(null);
},
], function() {
// this will run once all three functions above have finished
});
还不错吧?
希望对您有所帮助!
编辑:这是一个代码块,显示您上面使用 asyncjs 重构的代码:
async.waterfall([
function(cb) {
fse.copy(temp_path, new_location + file_name, function(err) {
if (err) {
log.error(err);
} else {
log.info("File saved to " + new_location + file_name);
var sourceImage = new_location + file_name;
log.debug(sourceImage);
log.debug(randomString);
}
console.log('Finished running fs.copy');
cb(null, sourceImage, randomString);
});
},
function(sourceImage, randomString, cb) {
iim(sourceImage, randomString, function(err) {
if (err) {
log.error(err);
}
console.log('Finished running iim');
cb(null, randomString);
});
},
function(randomString, cb) {
da(randomString, function(err) {
if (err) {
log.error(err);
}
console.log('Finished running da');
cb();
});
}
], function() {
console.log('All done!');
});