我有一个需要更新某些键的对象。更新是通过一个函数(从数据库获取信息)并返回一个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,但我还没有给它一个完整的尝试。有什么建议?
答案 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);
});