如何将 async 与其他异步模块一起使用?
Posted
技术标签:
【中文标题】如何将 async 与其他异步模块一起使用?【英文标题】:How to use async with other asynchronous modules? 【发布时间】:2014-06-18 05:28:41 【问题描述】:这是一个没有异步的工作测试程序:
var fs = require('fs');
function test()
var finalResponse = '', response = '';
function showFinalResponse()
console.log(finalResponse);
function processTheFile(err, data)
if (err)
finalResponse = 'Could not read the file';
else
response += data;
response += '</body></html>';
finalResponse = response;
showFinalResponse();
function readTheFile(exists)
if (!exists)
finalResponse = 'File does not exist.';
showFinalResponse();
else
response += '<!DOCTYPE html><html lang="en-US"><head></head><body>';
fs.readFile('file.txt', 'utf8', processTheFile);
fs.exists('file.txt', readTheFile);
;
test();
这是我尝试让相同的程序与异步瀑布一起工作。我在如何在异步和 fs 调用中传递回调时遇到问题。
var fs = require('fs');
var async = require('async');
function testAsync() var finalResponse, response = '';
async.waterfall( [
function checkIfTheFileExists(done)
fs.exists('file.txt', done);
,
function readTheFile(err, exists, done)
response += '<!DOCTYPE html><html lang="en-US"><head></head><body>';
fs.readFile('file.txt', 'utf8', done);
,
function processTheFile(err, data, done)
response += data;
response += '</body></html>';
finalResponse = response;
done(null);
],
function showFinalResponse(err)
if (err)
if (err.code === 'ENOENT') // intended to test for file is missing.
finalResponse = 'File does not exist.';
else // any other errors.
finalResponse = 'Could not read the file';
console.log(err);
console.log(finalResponse);
);
testAsync()
我无法让异步版本工作。我对回调的去向感到困惑。
【问题讨论】:
【参考方案1】:这是我的最终工作版本(以防它帮助其他人)。再次感谢您的帮助!
var fs = require('fs');
var async = require('async');
var addErrParm = function (err, done) return function(exists)
done(err, exists);
function testAsync() var finalResponse, response = '';
function checkIfTheFileExists(done)
fs.exists('file.txt', addErrParm(null, done));
function readTheFile(exists, done)
if (!exists)
done('notFound');
else
response += '<!DOCTYPE html><html lang="en-US"><head></head><body>';
fs.readFile('file.txt', 'utf8', done);
function processTheFile(data, done)
response += (data || 'The file is empty') + '</body></html>';
finalResponse = response;
done(null);
function showFinalResponse(err)
if (err)
finalResponse = (err === 'notFound' ? 'File does not exist.' : 'Could not read the file');
console.log(finalResponse);
async.waterfall([ checkIfTheFileExists,
readTheFile,
processTheFile
], showFinalResponse);
testAsync()
所以基本上,异步需要从除最终回调之外的所有函数中删除 err 参数(第一个参数),并且需要在除最终回调之外的所有函数上添加一个回调('done')作为额外参数。
另外,如果没有像 fs.exists 这样的 err 参数,您必须创建一个函数来模拟 err 参数,以便 async 可以将其删除。
【讨论】:
【参考方案2】:fs.exists
很奇怪,因为它没有向其回调函数提供错误参数。相反,它只提供一个exists
参数来指示是否找到了文件。据推测,如果有错误,exists
将是false
。因此,您需要将其回调包装在您自己的函数中,以便您可以为waterfall
回调提供单独的错误参数:
async.waterfall( [
function checkIfFileExists(done)
fs.exists('file.txt', function(exists) done(null, exists); );
,
function makeSureFileExists(exists, done)
...
请注意 the docs 中的警告,但通常不应使用 fs.exists
。
【讨论】:
我确实看到了该警告,但我正在使用它,因为我不想在某些情况下打开文件。我只想知道它是否存在。 请在下面的答案中查看我的最终版本。有什么问题吗?【参考方案3】:fs.exists('file.txt', done(null));
这会立即调用done
。您需要将实际的done
函数传递给fs.exists
:
fs.exists('file.txt', done);
其他人也一样。
【讨论】:
@ChrisG.:fs.exists
接受回调,如果有错误则将其传递给错误,如果没有则将 null
传递给它。在回调之前你不知道是否有错误。传递done
与传递function (error, result) done(error, result);
是一回事。
@ChrisG.: processFileFile
也不会出错。这就是大多数异步函数的用途;如果瀑布的任何部分出现错误,只有最终的回调会得到它,而介于两者之间的将被跳过。
好的,我认为正在取得进展。仍然无法正常工作。我编辑了问题以显示我最近的尝试。以上是关于如何将 async 与其他异步模块一起使用?的主要内容,如果未能解决你的问题,请参考以下文章