1

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

在此示例中,我在下一个滴答声中设置迭代回调以避免在同步调用许多回调时出现“超出最大调用堆栈大小”错误。

我还考虑创建 validateSync 和 validateAsync 函数来准确定义它们的作用。

这是一个不好的做法吗?您将如何使用此示例设计 api?

4

1 回答 1

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);
    }
}
于 2014-03-15T12:21:51.570 回答