如何避免使用node.js进行雪崩?

时间:2016-08-08 13:09:32

标签: node.js caching promise q

我想在节点服务器中缓存一些数据:

像这样的rpc数据提供者:

var cnt = 0;
function rpcDataProvider(areaId) {
    return Q.delay(100).then(() => {
        cnt += 1
        console.log("I am rpcDataProvider and I am not so fast. I am requested " + cnt + " times.");
        const base = areaId * 10;
        var arr = [];
        for (var i = 0; i < 10; i ++) {
            arr.push(base + i);
        }
        return arr;
    })
}

http服务器

// cache data
var provinceList;
var cityList;
var countyList;

function getProvinceList() {
    if (provinceList && provinceList.length > 0) return Q.resolve(provinceList);
    return rpcDataProvider(1).then((rv) => {
        provinceList = rv;
        return rv;
    });
}

function getCityList() {
    if (cityList && cityList.length > 0) return Q.resolve(cityList);

    return getProvinceList().then((provinceList) => {
        return Q.all(provinceList.map((item) => rpcDataProvider(item))).then(rvs => {
            cityList = rvs.reduce((prev, cur) => prev.concat(cur));
            return cityList;
        });

    });
}

function getCountyList() {
    if (countyList && countyList.length > 0) return Q.resolve(countyList);

    return getCityList().then((cityList) => {
        return Q.all(cityList.map((item) => rpcDataProvider(item))).then(rvs => {
            countyList = rvs.reduce((prev, cur) => prev.concat(cur));
            return countyList;
        })
    })
}

function api1() {
    console.log("I am http api1");
    return getProvinceList();
}

function api2() {
    console.log("I am http api2");
    return getCityList();
}

function api3() {
    console.log("I am http api3");
    return getCountyList();
}

function api4() {
    console.log("I am http api4");
    return getCountyList();
}

function api5() {
    console.log("I am http api5");
    return getCountyList();
}

客户请求:

function httpRequest() {
    console.log("I am client.");
    Q.all([api1(), api2(), api3(), api4(), api5()]);
}

httpRequest();

问题是 parallel请求缓存不起作用

1 个答案:

答案 0 :(得分:1)

不要缓存承诺值。缓和承诺。

// cache data
var provinceList;
var cityList;
var countyList;

function rpcReduceAndConcat(list) {
    return Q.all(list.map(rpcDataProvider)).then(rvs => {
        return rvs.reduce((prev, cur) => prev.concat(cur));
    });
}

function getProvinceList() {
    if (!provinceList) provinceList = rpcDataProvider(1);
    return provinceList;
}

function getCityList() {
    if (!cityList) cityList = getProvinceList().then(rpcReduceAndConcat);
    return cityList;
}

function getCountyList() {
    if (!countyList) countyList = getCityList().then(rpcReduceAndConcat);
    return countyList;
}