Я звоню в API, который возвращает список полей.Некоторые из этих полей имеют связанные поля, которые мне нужно запросить в API, чтобы получить эти поля.
Итак, вот что я пытаюсь сделать (в основном псевдокод):
// gets initial set of fields. This part works.
let fields = await getFields();
processFields(fields).then(data => {
console.log('data now contains object with all fields and related fields', data);
});
async function processFields(fields) {
let fieldObj = {};
return new Promise(resolve => {
fields.forEach(async field => {
if (field.collection) {
let related = await getRelated(field.relatedListFieldType);
fieldObj[field.id] = {
name: field.name,
display: field.display,
fields: related
};
} else {
fieldObj[field.id] = {name: field.name, display: field.display};
}
});
resolve(fieldObj);
});
}
async function getRelated(name) {
… some code here and return promise …
}
Проблема, с которой я сталкиваюсь, заключается в том, что forEach не ждет, поэтому при первом включении console.log я получаю все ожидаемые результаты, кроме полей, в которых есть коллекция.Так как я жду их, он никогда не попадет в возвращенное полеObj.Если я не жду там, я получаю их в поле Obj, но когда я распечатываю их, они просто обещания.Я безуспешно пытался использовать bluebird и библиотеку async npm, чтобы попытаться получить foreach, который будет ждать результатов перед разрешением, но мне это не удалось.Что я могу сделать, чтобы пройти через это?
Редактировать с новым кодом:
async function processFields(data) {
let fieldObj = {};
for (let field of data.data) {
if (field.isCollection) {
let related = await getRelated(field.relatedListFieldType);
fieldObj[field.id] = {
name: field.name,
display: field.display,
fields: related
};
} else {
fieldObj[field.id] = {
name: field.name,
display: field.display
}
}
}
return fieldObj;
}
async function getRelated(name) {
let relatedData = '';
name = name.toLowerCase();
if (objects[name]) {
return objects[name];
} else {
// put a placeholder here so we only request this once
objects[name] = {};
}
return new Promise(resolve => {
let relatedOptions = Object.assign(options, {
path: encodeURI(`/api/objects/v1/${name}/_describe`)
});
let req = https.request(relatedOptions, res => {
res.on('data', chunk => {
relatedData += chunk;
});
res.on('error', err => {
console.log('had error', err);
});
res.on('end', async () => {
objects[name] = await processFields(JSON.parse(relatedData));
resolve(objects[name]);
});
});
req.end();
});
}