使用节点Q更新对象值

时间:2014-08-12 21:22:11

标签: javascript node.js q

我有一个需要更新某些键的对象。更新是通过一个函数(从数据库获取信息)并返回一个promise。原始对象有许多键,只有一些需要更新。

// mocked response for demonstration
// the call01 function returns an array that make_obj function uses.
// the make_obj function returns an object like var obj.
// the get_data expects an array of ints and returns an array of strings like ['cat', 'dog', 'boat']


var obj = {'key1': {'a': [1,2,3], 'b': [2,3,4], 'c': [5,6,7]}, 'key2': {'a': [5,4,5], 'b': [9,8,9], 'c': [1,9,5]}}
var _ = require('lodash');


function updater(obj) {
    var deferred = Q.defer();

    _.forIn(obj, function(v,k) {
        get_data(v.a)
            .then(function(words) {
                v.a = words;
            });

        get_data(v.b)
            .then(function(words) {
                v.b = words;
            });
        deferred.resolve(obj);
    });

    return deferred.promise;

// call01 returns a promise
call01(some_val)
    .then(make_obj)
    .then(updater)
    .then(console.log)

我希望能看到类似的东西(授予我在这里编制价值):

{'key1': {'a': ['cat', 'dog', 'boat'], 'b': ['dog', 'boat', 'chair'] , 'c': [5,7,8]}, 'key2': {'a': ['spoon', 'chair', 'spoon'], 'b': ['tree', 'bird', 'tree'], 'c': [1,9,5]}}

我知道我可能需要有一个Q.all或Q.allSettled来聚合承诺,但我无法让它工作。

这是我用Q.all尝试过的。什么不工作是我无法弄清楚如何将var promises的结果映射回obj来更新值。

function updater(obj) {
    var deferred = Q.defer();

    // this is only making an array of get_data from el.a
    var promise_arr1 = _.map(obj, function(el){
        return get_data(el.a);    
    });

    // this is only making an array of get_data from el.b
    var promise_arr2 = _.map(obj, function(el){
        return get_data(el.b);
    });

    // I know this is not the right way to do it. the result flattened arr has no mapping back to the original obj. I wasn't sure how to make the update to obj.
    Q.all(_.flatten(promise_arr1, promise_arr2))
        .then(deferred.resolve)


    return deferred.promise;

我甚至考虑过使用async而不是q。我看到async有一个async.eachSeries,但我还没有给它一个完整的尝试。有什么建议?

1 个答案:

答案 0 :(得分:0)

我无法理解你的核心问题。这是你想要做的吗?

var Q = require("q");

var updateFrAsync = {'a': 0, 'b': 0, 'c': 0};

function sampleAsyncCallRandomWait(key) {
    var deferred = Q.defer();

    setTimeout(function() {
        updateFrAsync[key] = Math.random();
        deferred.resolve();
    }, Math.random());

    return deferred.promise;
}

promises = [sampleAsyncCallRandomWait('a'),sampleAsyncCallRandomWait('c')]

Q.allSettled(promises)
    .then(function (results) {
        console.log(updateFrAsync);
    });