Проблема возникает из-за того, что вы пытаетесь поделиться this.promised
между update()
и асинхронным поведением внутри parseItem()
.
. Чтобы исправить это, вы можете вместо этого вернуть Promise
из parseItem()
, которыйпредставляет каждый Promise
, созданный внутри.
Например, упрощенная версия этого:
async parseItem(relation) {
const result = await ask(relation);
return await Promise.all(result.map(i => {
const relations = i.relations;
return Promise.all(relations.map(parseItem));
}));
}
Как вы можете видеть, внутри parseItem()
мы ждем, пока все вернется, прежде чемразрешение Promise
.
Чтобы применить это к вашему коду, оно может выглядеть примерно так:
async parseItem(relation) {
if (relation.wasResolved === true) {
return true;
}
console.log('Parsing ' + relation.displaytitle);
const result = await this.MediaWiki.ask('[[Has source element::' + relation.fulltext + ']]|?Has target element');
const nestedPromises = result.map(el => {
const targetElements = el.printouts['Has target element'];
// This returns an array of an array of promises
return targetElements
.map(tel => this.getIndex(tel))
.filter(index => index !== -1)
.map(index => {
this.elementsInView[index].parent = relation;
// This returns a promise
return this.parseItem(this.elementsInView[index]);
});
});
// Easy way to flatten array of arrays
const promises = [].concat.apply([], nestedPromises);
await Promise.all(promises);
// Set wasResolved to true
relation.wasResolved = true;
return true;
}
Хотя я не могу гарантировать, что это будет работать.Это зависит от природы этой структуры данных и от того, какой эффект она имеет, чтобы изменить ее, решая все эти обещания.
Основная проблема, которая вызывает вопросы, - это строка:
this.elementsInView[index].parent = relation;
ЧтоЭффект это имеет на parseItem
?И в результате этой мутации меня теперь беспокоило, могут ли множественные элементы, переданные в parseItem
на update
, которые выполняются в режиме чередования, одновременно изменять данные, от которых они зависят.
По крайней мере, с точки зрения исходного вопроса, этот метод должен помочь вам дождаться выполнения всех обещаний.