如何解析递归 JSON 中的承诺



我需要递归地通过JSON,在某些情况下调用远程API。我需要返回最后修改的整个 JSON,但我不知道如何等到所有承诺都兑现

const getObjectsOfRelated = (xmlAsJson, token) => {
if (testIfIwantCallApi()) {   
const jsonToReturn = JSON.parse(JSON.stringify(xmlAsJson))
jsonToReturn.elements = callApi(xmlAsJson.text).then(result => {
return result.data
})
return jsonToReturn
}
if (xmlAsJson.elements) {
const jsonToReturn = JSON.parse(JSON.stringify(xmlAsJson))
jsonToReturn.elements = xmlAsJson.elements.map(res => getObjectsOfRelated(res, token))
return jsonToReturn
}
return xmlAsJson
}

即使我尝试使用 setTimeout 破解它,结果也不包括使用外部 API 创建的部件。

这样,代码返回带有承诺而不是值的正确结构,我希望它要么返回已完成的承诺,要么能够等到承诺实现

使用Promise.resolve包装 Promise 中的普通返回值:

const getObjectsOfRelated = (xmlAsJson, token) => {
if (testIfIwantCallApi()) {   
const jsonToReturn = JSON.parse(JSON.stringify(xmlAsJson))
return callApi(xmlAsJson.text).then(result => {
jsonToReturn.elements = result.data;
return jsonToReturn;
})
}
if (xmlAsJson.elements) {
const jsonToReturn = JSON.parse(JSON.stringify(xmlAsJson))
Promise.all(xmlAsJson.elements.map(res => getObjectsOfRelated(res, 
token)).then((results) => {
jsonToReturn.elements = results.map(result => result.data);
return jsonToReturn;
});
}
return Promise.resolve(xmlAsJson);
}

这样,您将始终如一地返回承诺,并且可以像这样使用您的函数:getObjectsOfRelated(xmlAsJson, token).then(result => console.log(result))

您可以使用"Promise.all"...

对于简单数组,您可以在数组上映射一个函数: 该函数为每个元素的"新值"返回一个承诺。 如果您使用 Bluebird 承诺,您甚至可以返回承诺和普通值的混合。 (不必将纯值包装在"Promise.resolve"中( 然后你把承诺数组传递给"Promise.all((",等待所有承诺完成。

要转换树形数据结构(如 JSON(,您需要执行相同的操作,但要递归。 树中的每个节点将使用"Promise.all"来等待其所有子节点=,并且根节点只有在树中的每个节点都解析后才会"解析"。

请注意,"Promise.all"将同时运行所有异步函数。 如果你不想这样,你可以改用"Promise.mapSeries",它做同样的事情,但它在开始下一个之前等待每个异步函数。 如果您有大量数据并且不想同时启动太多同步函数,这可能会更好。

相关内容

最新更新