【发布时间】:2012-09-30 23:51:14
【问题描述】:
我有一些看起来像这样的同步代码:
function bulk_upload(files, callback) {
for (file in files) {
sync_upload(file); // blocks till file uploads
}
print('Done uploading files');
callback();
}
我现在必须使用异步 API async_upload(file, callback) 而不是 sync_upload(file) 来做同样的事情。我有多种选择,但不确定什么是最好的:
1) 在 for 循环之后使用 sleep - 这是一个 hack,因为我希望我的时机是正确的
2) 递归链接我的数组:
function bulk_upload(files, callback) {
if (files.length == 0) {
print('Done uploading files');
callback();
} else {
async_upload(files.removeLast(), function() { bulk_upload(files, callback); });
}
}
这不仅是 hacky,而且是次优的,因为我可以使用新的 async_upload API 并行上传我的文件,但我最终按顺序上传。
3) 使用全局计数器:
function bulk_upload(files, callback) {
uploads = 0
for(file in files) {
async_upload(file, function() { uploads++; });
}
while(uploads < files.length) ; // Empty spin - this is stupid
print('Done uploading files');
callback();
}
4) 稍微好一点的计数器(但仍然很糟糕):
function bulk_upload(files, callback) {
uploads = 0
for(file in files) {
async_upload(file, function() {
if (++uploads == files.length) { // this becomes uglier as I want to await on more stuff
print('Done uploading files');
callback();
};
});
}
}
【问题讨论】:
-
您可以使用期货来实现这一点。 [这里][1] 有一个很好的例子。 [1]:stackoverflow.com/questions/5989538/…
-
期货答案是最干净的方式,而您的 4) 是另一种 mroe 标准方式,尽管通常包含在帮助程序中。我只是想指出你的 1) 和 3) 无论如何都行不通。你的自旋锁永远不会完成,因为 Javascript 使用单线程,所以当你的 while 循环时,上传回调不可能运行。
-
请注意,选项 3) 不可行;在紧密循环中阻塞将阻止任何
async_uploads 回调运行,因此您将无限循环。
标签: node.js design-patterns asynchronous callback synchronous