我应该如何在节点中执行此操作?快速路径和慢速路径

时间:2015-08-21 00:35:39

标签: javascript node.js asynchronous

我有一些通过快速路径获取数据的代码,如果快速路径不可用,我想实现回退到慢速路径。这里仍然是node.js的新手,所以我不知道该怎么做。

这是我的意思的一个简单例子:

function getThing(callback) {
    var thang = getThingTheFastWay();
    if (!thang) {
        thang = getThingTheSlowWay();
    }
    if (!thang || !thang.validate()) {
        return callback(new Error('invalid thang'));
    }
    callback(null, thang);
}

所以我的目标是异步执行getThingTheSlowWay()中的I / O.此方法的后半部分是否需要提供给getThingTheSlowWay()的回调?

4 个答案:

答案 0 :(得分:1)

  

此方法的后半部分是否需要提供给getThingTheSlowWay()的回调?

是的,确切地说。您无法为异步结果执行thang =。你的功能基本上是这样的:

function getThing(callback) {
    var thang = getThingTheFastWay();
    if (thang) {
        if (!thang.validate())
            callback(new Error('invalid thang'));
        else
            callback(null, thang);
    } else {
        getThingTheSlowWay(function(err, thang) {
            if (!err && !thang.validate())
                callback(new Error('invalid thang'));
            else
                callback(err, thang);
        });
    }
}

为避免重复,您需要使用命名函数:

function getThing(callback) {
    function validateThang(err, thang) {
        if (!err && !thang.validate())
            callback(new Error('invalid thang'));
        else
            callback(err, thang);
    }
    var thang = getThingTheFastWay();
    if (thang)
        validateThang(null, thang);
    else
        getThingTheSlowWay(validateThang);
}

另一种方法是使用承诺。假设getThingTheSlowWay返回一个承诺而getThingTheFastWay没有承诺,它看起来像

function getThing() {
    return Promise.resolve(getThingTheFastWay() || getThingTheSlowWay())
    .then(function validateThang(thang) {
        if (thang.validate())
            return thang;
        else
            throw new Error('invalid thang');
    });
}

答案 1 :(得分:1)

我建议你总是使用回调,无论是否有什么东西快速"或不。仅仅因为你认为速度快,并不意味着它总会如此 - 而且在高性能服务器的领域,为什么要写一些可以阻止它的东西同样容易?

function getThing(callback) {
    var thang = getThingTheFastWay(function(err, thang) {
        if (thang && !err) {
            callback(err, thang);
        } else {
            getThingTheSlowWay(function(err, thang) {
                callback(err, thang);
            });
        }
    });
}

这当然需要对你的下游函数进行一些重写来支持回调,但值得做。即使您正在使用第三方功能来执行此操作,也可以将自己的回调包装在长时间运行的函数中。

答案 2 :(得分:0)

考虑使用承诺。 https://www.promisejs.org/承诺允许您执行某些操作,并在完成后执行回调。如果快速操作失败,则可以使用慢速操作进行恢复。所有这些行动都可以与承诺一起使用。

要考虑的一件事是,慢速操作可能不会慢,因为快速操作通常会阻塞。遇到大量请求时可能会出现问题。

如果您不想使用promises,请检查快速版本是否有效并立即执行回调并返回。如果它还没有返回,你可能需要将回调传递给get slow way函数,因为那将有一个异步调用,它将有一个回调来调用回调参数

答案 3 :(得分:0)

Promise在这里可能有用:

function getThing() {
    return new Promise(function(resolve, reject) {
        getThingTheFastWay().then(function(result) {
            resolve(result);
        }).catch(function() {
            getThingTheSlowWay().then(function(result) {
                resolve(result);
            }).catch(function() {
                reject();
            });
        });
    });
}

使用它将是:

getThing().then(function(result) {
    // do something with the result
});

您可以使用和声标志启用承诺,或使用bluebird等库(推荐)