我使用loadash map函数来做一些数据结构。数据返回一组id,我需要查询数据库并将结果添加到地图然后返回,但稍后返回数据,我的函数首先返回。如何使map返回等待然后返回函数。
let result = _.chain(value)
.groupBy('pubId')
.pairs()
.map(function(currentItem) {
let item = _.object(_.zip(['ID', 'targetting'], currentItem));
propsToBeDeleted.forEach(function(prop) {
item.targetting.forEach(d => {
item.publishername = d.RTB.name;
item.type = d.type;
delete d[prop];
});
});
item.targetting.map(d => {
if (d.type == 15) {
d.name = Object.keys(JSON.parse(d.value));
d.value = Object.values(JSON.parse(d.value))[0];
item.dspIds = [];
}
if (d.type == 16) {
let value = JSON.parse(d.value);
d.name = Object.keys(JSON.parse(d.value)).filter(d => d != 'profileId');
d.value = value;
item.dspIds = d.value.profileId;
dspAccount.find({where: {id: 139}}, (err, data) => {
// async call wait here to get data and attach to item
item.x = data ;
});
delete d.value.profileId;
d.value = JSON.stringify(d.value);
}
});
return item;
})
.value();
我也尝试过使用承诺
promises.push(new Promise((resolve, reject) => {
if (data.id) {
XX.upsertWithWhere({id: data.id}, payload, (err, data) => {
if (err) {
return reject(err);
}
return resolve(data);
});
}
}));
});
Promise.all(promises).then((data) => {
callback(null, data);
}, err => {
callback(err);
});
更新 我已经列出了promise .all方法无效。所以它不能称为重复
答案 0 :(得分:0)
事情有点棘手,因为你有一个外部.map()
和一个内部.map()
,包含一个异步元素。
异步元素有效地使整个事物异步,需要:
.map()
生成的Promise数组与Promise.all()聚合,聚合Promise返回到外部.map()
。.map()
生成的Promise数组与Promise.all()聚合在一起。.then()
。首先,要使主代码块更简单易读,请创建dspAccount.findAsync()
的预定版本。
dspAccount.findAsync = function(query) {
return new Promise(function(resolve, reject) {
dspAccount.find(query, (err, data) => {
if(err) {
reject(err);
} else {
resolve(data);
}
});
});
}
然后主代码块可以写成如下:
let outerPromises = _.chain(value)
.groupBy('pubId')
.pairs()
.map(function(currentItem) {
let item = _.object(_.zip(['ID', 'targetting'], currentItem));
item.targetting.forEach(d => {
item.publishername = d.RTB.name;
item.type = d.type;
propsToBeDeleted.forEach(function(prop) {
delete d[prop];
});
});
let innerPromises = item.targetting.map(d => {
let value = JSON.parse(d.value);
if (d.type == 15) { // synchronous - `innerPromises` receives a null
item.dspIds = []; //
d.name = Object.keys(value);
d.value = Object.values(value)[0];
return null;
}
if (d.type == 16) { // asynchronous - `innerPromises` receives a Promise
return dspAccount.findAsync({where: {id: 139}})
.then(data => {
d.name = Object.keys(value).filter(d => d != 'profileId');
item.dspIds = value.profileId;
delete value.profileId;
item.x = data;
d.value = JSON.stringify(value);
});
}
});
return Promise.all(innerPromises).then(() => item); // aggregate inner promises and return
})
.value(); // returns the outerPromises array
Promise.all(outerPromises) // aggregate outer promises
.then(items => {
// do stuff with items here
})
.catch(error => {
// something went wrong
// log/display error
// take remedial action as required
});
我希望还有一些工作要做。在item
循环中item.targetting.map()
应该变异,看起来并不正确。 item.targetting
传递其结果(同步或异步)的最后一个元素将决定item
的组成。这可能不是你想要的。如果它是你想要的,那么就需要更多的控制来确保最后传递的结果是item.targetting
的最终元素产生的结果。