Javascript Typescript/JS递归承诺
我正在学习Javascript,我一直在使用承诺 我试图从API文档中创建一个树状结构,其中JSON中的$ref键被替换为文件中其他地方的API对象。这需要在相当同步的情况下发生,在我遍历API对象的键时,当我找到$ref时,它会在JSON中被查找和替换 e、 gJavascript Typescript/JS递归承诺,javascript,typescript,promise,Javascript,Typescript,Promise,我正在学习Javascript,我一直在使用承诺 我试图从API文档中创建一个树状结构,其中JSON中的$ref键被替换为文件中其他地方的API对象。这需要在相当同步的情况下发生,在我遍历API对象的键时,当我找到$ref时,它会在JSON中被查找和替换 e、 g 我从这个函数中得到一个API对象列表,我认为这些对象在API中是更重要的对象。strong>定义是文件的内容,包含所有API对象 function fillObjectTree(parents: string[]) { con
我从这个函数中得到一个API对象列表,我认为这些对象在API中是更重要的对象。strong>定义是文件的内容,包含所有API对象
function fillObjectTree(parents: string[]) {
console.log(parents);
Object.keys(definitions).map(apiTitle => {
// if the apiTitle is part of the parents list than we process it
if (parents.includes(apiTitle)) {
// Read the children and see if any references are part of the parent
let par = readChildren(definitions[apiTitle])
par.then(function (vals) {
// Do something with values
})
}
})
}
下一步是读取此API对象的属性并查找$ref键
function readChildren(definition: { properties: any; }) {
return new Promise((resolve, reject) => {
// Get the properties of the definition
let props = definition.properties;
// Properties are not always present on an object.
if (props) {
Object.keys(props).map(propName => {
Object.keys(props[propName]).map(elem => {
if (elem.includes("$ref")) {
// locationURL = the full url for the reference
let locationURL: string = props[propName][elem];
// returns the needed value for the URL based on the regex
let partialURL: string = locationURL.match('(?<=(\#\/.*\/)).*')[0];
readReference(partialURL).then((body) => {
console.log(body);
delete definition.properties[propName];
definition.properties[propName] = body;
});
}
})
})
resolve(definition);
} else {
resolve(definition);
}
});
}
那怎么了?
操作顺序似乎和我想发生的不匹配。该对象在JSON中不被替换,在执行时也不等待。我宁愿不使用wait或async,但尽可能保持它的基线承诺。
readChildren
将同步执行,直到它到达此块:
readReference(partialURL).then((body) => {
console.log(body);
delete definition.properties[propName];
definition.properties[propName] = body;
});
readReference
将返回一个承诺,因此它将获得承诺,然后安排中的任何内容,然后在将来的某个时间发生。然后函数继续,最终调用resolve(定义)代码>然后退出函数。这发生在宇宙内部之前
进行解析(定义)代码>发生在所有其他事件之后,只需将其放入然后
块即可
编辑:上述解决方案不处理地图
异步结果的处理列表:
const promises = list.map(element => {
return someAsyncFunction(element);
});
Promise.all(promises)
.then(results => {
... do stuff with the results
});
顺便说一句,如果您使用非常优秀的async/await语法,所有这些都会变得平淡无奇。对订购进行推理变得容易多了。一些关于一般承诺用法的快速提示:1。切勿使用new
创建承诺,除非您希望“承诺”某个基于回调的异步函数2。改为使用承诺链接,这意味着您应该始终返回您的承诺,尤其是内部的承诺,然后
3。要等待一系列承诺完成(如在.map
s中),请使用Promise。所有(…承诺列表…
这不会停止我的循环吗?我的问题是,可以有多个引用,我想返回apiDef并替换所有引用。更新了答案。
readReference(partialURL).then((body) => {
console.log(body);
delete definition.properties[propName];
definition.properties[propName] = body;
});
const promises = list.map(element => {
return someAsyncFunction(element);
});
Promise.all(promises)
.then(results => {
... do stuff with the results
});