Я подозреваю, что вы ищете
async function getData(providerName) {
const { url, requires } = dataProviders[providerName];
let urlParam = '';
if (requires != null) {
const requiredData = await new Promise(resolve => {
dataProviders[requires].observer.subscribe(() => {
resolve(allData[requires]);
});
// getData(requires); ???
});
urlParam += requiredData.parameter;
}
const result = await $.getJSON(url + urlParam);
allData[providerName] = result;
dataProviders[providerName][observer].notify(allData);
}
Вы могли бы упростить подписку на обратный вызов resolve
r, если вы уведомили своих наблюдателей с указанием c result
, а не allData
, Тем не менее, я полагаю, вы могли бы вообще отбросить этот класс Observer
и просто использовать обещание, если вы не извлекаете данные несколько раз. Это позволит вам избавиться от магазина allData
и просто запомнить обещание, возвращаемое getData
, что значительно упростит весь код:
const dataProviders = {
provderA: {
url: 'http://provder.a.com',
promise: null,
requires: null
},
providerB: {
url: 'http://provder.b.com',
promise: null,
requires: 'providerA'
}
};
function getDataOnce(providerName) {
const provider = dataProviders[providerName];
if (provider.promise == null)
provider.promise = getData(provider);
return provider.promise;
}
async function getData({ url, requires }) {
let urlParam = '';
if (requires != null) {
const requiredData = await getDataOnce(requires);
urlParam += requiredData.parameter;
}
const result = await $.getJSON(url + urlParam);
return result;
}
const consumers = {
consumerX: {
provider: 'providerA'
},
consumerY: {
provider: 'providerB'
},
consumerZ: {
provider: 'providerB'
}
};
for (const consumer of Object.values(consumers)) {
getDataOnce(consumer.provider).then(data =>
console.log('process data');
console.log(data)
});
}