У меня возникла проблема, которую я не совсем понимаю. Я чувствую, что есть вероятные концепции, которые я не понял, код, который можно оптимизировать, и, возможно, ошибка, добавленная для хорошей меры.
Чтобы значительно упростить общий поток:
- Сделан запрос к внешнему API
- Возвращенный объект JSON анализируется и сканируется на предмет ссылок на ссылки.
- Если найдены какие-либо ссылки на ссылки, делаются дополнительные запросы для заполнения / замены ссылок ссылок реальными данными JSON.
- После замены всех ссылок на ссылки возвращается исходный запрос, который используется для создания контента.
Вот исходный запрос (№1):
await Store.get(Constants.Contentful.ENTRY, Contentful[page.file])
Store.get представлен:
async get(type, id) {
return await this._get(type, id);
}
Какие звонки:
_get(type, id) {
return new Promise(async (resolve, reject) => {
var data = _json[id] = _json[id] || await this._api(type, id);
console.log(data)
if(isAsset(data)) {
resolve(data);
} else if(isEntry(data)) {
await this._scan(data);
resolve(data);
} else {
const error = 'Response is not entry/asset.';
console.log(error);
reject(error);
}
});
}
Вызов API:
_api(type, id) {
return new Promise((resolve, reject) => {
Request('http://cdn.contentful.com/spaces/' + Constants.Contentful.SPACE + '/' + (!type || type === Constants.Contentful.ENTRY ? 'entries' : 'assets') + '/' + id + '?access_token=' + Constants.Contentful.PRODUCTION_TOKEN, (error, response, data) => {
if(error) {
console.log(error);
reject(error);
} else {
data = JSON.parse(data);
if(data.sys.type === Constants.Contentful.ERROR) {
console.log(data);
reject(data);
} else {
resolve(data);
}
}
});
});
}
Когда запись возвращается, она сканируется:
_scan(data) {
return new Promise((resolve, reject) => {
if(data && data.fields) {
const keys = Object.keys(data.fields);
keys.forEach(async (key, i) => {
var val = data.fields[key];
if(isLink(val)) {
var child = await this._get(val.sys.linkType.toUpperCase(), val.sys.id);
this._inject(data.fields, key, undefined, child);
} else if(isLinkArray(val)) {
var children = await* val.map(async (link) => await this._get(link.sys.linkType.toUpperCase(), link.sys.id));
children.forEach((child, index) => {
this._inject(data.fields, key, index, child);
});
} else {
await new Promise((resolve) => setTimeout(resolve, 0));
}
if(i === keys.length - 1) {
resolve();
}
});
} else {
const error = 'Required data is unavailable.';
console.log(error);
reject(error);
}
});
}
Если ссылки на ссылки найдены, выполняются дополнительные запросы, а затем полученный JSON вставляется в исходный JSON вместо ссылки:
_inject(fields, key, index, data) {
if(isNaN(index)) {
fields[key] = data;
} else {
fields[key][index] = data;
}
}
Заметьте, я использую async
, await
и Promise
, я верю в их предназначение. Что в итоге происходит: вызовы данных, на которые имеются ссылки (получаются в результате _scan), в конечном итоге происходят после того, как исходный запрос был возвращен. Это приводит к тому, что в шаблон контента предоставляются неполные данные.
Дополнительная информация о настройке моей сборки:
return new Promise(async (resolve, reject) => { ... }
? Разве это не должно бытьasync _get(type, id) { ... }
и вообще никакого обещания? - person Shanoor   schedule 19.12.2015