我读过在函数中混合同步和异步操作是不好的做法(例如http://nodejs.org/api/process.html#process_process_nexttick_callback)。
现在我想迭代一系列我想要保存在数据库中的文档。在保存开始之前,我需要逐步验证所有文档。可以在api之后创建一个特定的验证器。
validate函数可以是完全同步的(简单检查字段,如果它们有效,如doc.sum> 10),但也是异步的(如果我需要获取并验证依赖文档)。
使用异步库(https://github.com/caolan/async)我有类似的东西:
function validateAll(docs) {
async.eachSeries(docs, function (doc, callback) {
var async = false;
validate(doc, function () {
if (async) {
callback();
} else {
process.nextTick(function () {
callback();
});
}
});
async = true;
});
}
function validate(doc, callback) {
if (doc.sum < 10) {
return callback(new Error("Invalid sum"));
}
if (doc.otherDocumentId) {
validateOtherDocFromDbAsync(doc.otherDocumentId, callback); // collection.find() or something
} else {
callback();
}
}
在这个例子中,我在下一个tick上设置了迭代回调,以避免超过&#34;最大调用堆栈大小&#34;如果同步调用多个回调,则会出错。
我还想过创建validateSync和validateAsync函数来准确定义它们的作用。
这是一种不好的做法吗?你会如何用这个例子设计api?
答案 0 :(得分:1)
这是一种不好的做法吗?
是。 http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony
您将如何使用此示例设计api?
不应该将回调传递给处理是否异步调用的validate
,而应该让validate
函数始终异步:
function validateAll(docs) {
async.eachSeries(docs, validate);
}
function validate(doc, callback) {
if (doc.sum < 10) {
process.nextTick(function () {
callback(new Error("Invalid sum"));
});
} else if (doc.otherDocumentId) {
validateOtherDocFromDbAsync(doc.otherDocumentId, callback); // collection.find() or something
} else {
process.nextTick(callback);
}
}