Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Typescript/JS递归承诺_Javascript_Typescript_Promise - Fatal编程技术网

Javascript Typescript/JS递归承诺

Javascript 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

我正在学习Javascript,我一直在使用承诺

我试图从API文档中创建一个树状结构,其中JSON中的$ref键被替换为文件中其他地方的API对象。这需要在相当同步的情况下发生,在我遍历API对象的键时,当我找到$ref时,它会在JSON中被查找和替换

e、 g

我从这个函数中得到一个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
  });