Api设计用于不安全的异步功能

时间:2014-03-15 12:11:38

标签: javascript node.js node-async

我读过在函数中混合同步和异步操作是不好的做法(例如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?

1 个答案:

答案 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);
    }
}