在下面的代码中,expiringContentsAllBU
填充在getOnlyContentWhatsNewReport
内的async / await函数array.map()
中,但expiringContentsAllBU
在businessUnits.map()
函数外部访问时变为空。
const getExpiringContents = async () => {
let businessUnits = Object.keys(contentFulSpaces);
let expiringContentsAllBU = [];
businessUnits.map( async (bu) => {
await getOnlyContentWhatsNewReport(bu, (err, result) => {
if(result) {
let expiringContentsByBU = {};
expiringContentsByBU['businessUnit'] = bu;
expiringContentsByBU['expiringContents'] = result;
expiringContentsAllBU.push(JSON.parse(JSON.stringify(expiringContentsByBU)));
} else console.log('No expiring contents found for WhatsNewSection');
})
});
console.log('result', expiringContentsAllBU);
}
var getOnlyContentWhatsNewReport = Promise.resolve(123);
const getExpiringContents = async () => {
let businessUnits = [{ id: 1 }, { id: 2 }, { id: 3 }];
const expiringContentsAllBU = await Promise.all(businessUnits.map(async (bu) => {
return getOnlyContentWhatsNewReport.then(respBu => {
bu.businessUnit = respBu;
return bu;
}).catch((err) => {
console.log('No expiring contents found for WhatsNewSection');
return null;
});
}));
console.log('result', expiringContentsAllBU);
}
getExpiringContents();
您必须等到地图完成并完成所有回调。 console.log
和后续代码块将在地图完成之前执行,因此
const getExpiringContents = async () => {
let businessUnits = Object.keys(contentFulSpaces);
const expiringContentsAllBU = await Promise.all(businessUnits.map(async (bu) => {
return getOnlyContentWhatsNewReport(bu, (err, result) => {
if(result) {
let expiringContentsByBU = {};
expiringContentsByBU['businessUnit'] = bu;
expiringContentsByBU['expiringContents'] = result;
return JSON.parse(JSON.stringify(expiringContentsByBU);
} else {
console.log('No expiring contents found for WhatsNewSection');
return null;
}
})
}));
console.log('result', expiringContentsAllBU);
}
由于map
不知道异步函数,你需要使用的东西。一个例子是Bluebird Promise.map
等价物:
const getExpiringContents = async () => {
let businessUnits = Object.keys(contentFulSpaces);
// Use Promise.map here to convert each businessUnit entry into a record
let expiringContentsAllBU = await Promise.map(businessUnits, async (bu) => {
await getOnlyContentWhatsNewReport(bu, (err, result) => {
if (!result) {
console.log('No expiring contents found for WhatsNewSection');
return;
}
let expiringContentsByBU = {};
expiringContentsByBU['businessUnit'] = bu;
expiringContentsByBU['expiringContents'] = result;
return JSON.parse(JSON.stringify(expiringContentsByBU));
})
});
// As this may contain undefined elements, remove those
expiringContentsAllBU = expiringContentsAllBU.filter(e => e);
console.log('result', expiringContentsAllBU);
}
如果你让getOnlyContentWhatsNewReport
返回一个promise,而不是使用回调方法,你可以将这段代码更平坦一些。 async
不会等待回调方法,所以请确保也返回一个承诺,否则此代码将无法正常等待。
完全承诺的版本重构了一点看起来像这样:
const getExpiringContents = async () => {
let businessUnits = Object.keys(contentFulSpaces);
let expiringContentsAllBU = await Promise.map(businessUnits, async businessUnit => {
let expiringContents = await getOnlyContentWhatsNewReport(businessUnit);
if (!expiringContents) {
console.log('No expiring contents found for WhatsNewSection');
return;
}
// Choosing names that match the output means you can use the destructuring operator
let expiringContentsByBU = {
businessUnit,
expiringContents
};
// A more formalized "clone" function could help here.
return JSON.parse(JSON.stringify(expiringContentsByBU));
});
// As this may contain undefined elements, remove those
expiringContentsAllBU = expiringContentsAllBU.filter(e => e);
console.log('result', expiringContentsAllBU);
}
你可以将你的.map()
改为for loop
。
或者在你的.map()
函数中,返回promises。然后你可以打电话给await Promise.all(promiseArray)
使用与某些lodash函数的异步来实现理智会有所帮助 -
getExpiringContents = async() => {
let businessUnits = Object.keys(contentFulSpaces);
let expiringContentsAllBU = await Promise.map(businessUnits, async businessUnit => {
let expiringContents = await getOnlyContentWhatsNewReport(businessUnit);
if (_.isEmpty(expiringContents)) {
console.log('No expiring contents found for WhatsNewSection');
return;
}
// Choosing names that match the output means you can use the destructuring operator
let expiringContentsByBU = {
businessUnit,
expiringContents
};
// A more formalized "clone" function could help here.
return _.cloneDeep(expiringContentsByBU);
});
// As this may contain undefined elements, remove those
expiringContentsAllBU = _.compact(expiringContentsAllBU);
console.log('result', expiringContentsAllBU);
}