【发布时间】:2020-10-13 06:33:06
【问题描述】:
我正在学习 Javascript,但我一直在使用 Promises。
我正在尝试从 API 文档中创建一个树状结构,其中 JSON 中的 $ref 键被替换为位于文件中其他位置的 API 对象。这需要相当同步地发生,在我遍历 API 对象的键时,当我找到一个 $ref 时,它会在 JSON 中查找并替换。
例如
"apiStorageVersion": {
"description": "...",
"properties": {
"apiVersion": {
"description": "...",
"type": "string"
},
"kind": {
"description": "...",
"type": "string"
},
"metadata": {
"$ref": "#/definitions/apiMetaData",
"description": "..."
},
"spec": {
"$ref": "#/definitions/apiSpec",
"description": "..."
},
"status": {
"$ref": "#/definitions/apiStatus",
"description": "..."
}
}
}
我从这个函数开始,它获取我认为是父对象的 API 对象列表,从某种意义上说,这些对象是 API 中更重要的对象。 Definitions 是文件的内容,包含所有 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);
}
});
}
找到引用时,会调用第二个函数,在当前文件中查找该对象。
function readReference(apiTitle: string) {
return new Promise((resolve, reject) => {
// Check all the definitions and find a match
Object.keys(definitions).map(apiDef => {
if (apiTitle === apiDef) {
readChildren(definitions[apiDef]).then((body) => {
resolve(body);
})
}
})
})
}
所以出了什么问题? 好吧,操作顺序似乎与我想要发生的不匹配。对象在 JSON 中没有被替换,执行时也没有等待。我宁愿不使用 await 或 async,但尽可能将其保持在基线 Promises 中。
【问题讨论】:
-
一些关于一般 Promise 用法的快速提示:1. 永远不要使用
new创建 Promise,除非你想“承诺”一些基于回调的异步函数 2. 改用 Promise 链,这意味着你应该始终return你的承诺,尤其是在then3. 等待一系列承诺完成(如在.maps 中)使用Promise.all(...list of promises...)
标签: javascript typescript promise