简单的代码路径,最好用要点解释
问题
步骤5在步骤4完成之前发生(下面的代码)
//api endpoint
router.post('/get-data', getObjects);
export const getObjects: express.RequestHandler = (req, res) => {
queryContainer(containerId, querySpec)
.then((result) => {
return getChildren(result, req.body.criteria);
})
.then((result) => {
res.send(result);
});
}
export async function queryContainer(containerId, querySpec) {
const { result: results } = await client.database(databaseId).container(containerId).items.query(querySpec, {enableCrossPartitionQuery: true}).toArray()
.catch( (error) => {
console.log("Error! ", error);
});
return results;
}
function getChildren(result: any, criteria: any) {
if(criteria) {
result.children = [];
var actions = result
.map(result => result.element)
.map(dbCallToGetChildren);
var results = Promise.all(actions);
results.then(children => {
result.children.push(...children)
return result;
});
}
return result;
}
export const dbCallToGetChildren = (async function (username) {
const querySpec = {
query: "SELECT * FROM root r WHERE r.userName=@userName",
parameters: [
{name: "@userName", value: username}
]
};
queryContainer(containerId, querySpec)
.then((results) => {
return results;
})
.catch((error) => {
console.log("Error " + error);
return Promise.resolve;
});
});
答案 0 :(得分:0)
第5步发生在第4步(getChildren
函数)完成之前,因为getChildren
没有返回Promise。将其更改为以下内容可能会解决问题:
function getChildren(result: any, criteria: any) {
return new Promise(resolve => {
if(criteria) {
result.children = [];
var actions = result
.map(result => result.element)
.map(dbCallToGetChildren);
var results = Promise.all(actions);
results.then(children => {
result.children.push(...children)
resolve(result);
});
} else {
resolve(result);
}
});
}
在results.then(children => { ... }
内现在有resolve(result);
,以确保return getChildren(result, req.body.criteria);
调用中的queryContainer
语句在Promise解决之前不会完成。
答案 1 :(得分:0)
为了使第4步在执行第5步之前完全完成,我们需要说明通过getChildren
的每个代码路径。
这意味着我们应该对此进行更改:
function getChildren(result: any, criteria: any) {
if(criteria) {
result.children = [];
var actions = result
.map(result => result.element)
.map(dbCallToGetChildren);
var results = Promise.all(actions);
results.then(children => {
result.children.push(...children)
return result;
});
}
return result;
}
进入以下内容(注意代码注释):
function getChildren(result: any, criteria: any) {
if(criteria) {
result.children = [];
var actions = result
.map(result => result.element)
.map(dbCallToGetChildren);
var results = Promise.all(actions);
return results.then(children => { // returns a promise
result.children.push(...children)
return result;
});
}
return Promise.resolve(result); // returns a promise
}
重要的是return
,否则此行中的代码将以异步方式执行(这不能保证第4步将在第5步开始之前完成)。
答案 2 :(得分:0)
我对您的代码有几点评论:
result.children = []
避免使用any并尝试定义类型
在您的代码中是因为您正在进行突变,所以您甚至不需要返回结果,因为原始对象已被更改,但是正如我之前提到的,您应该避免突变。
在第4步之前执行第5步的主要问题是getChildren不会返回promise,我对您的代码进行了一些更改以适应promise。
function getChildren(result: any, criteria: any): Promise<any> {
return new Promise((resolve, reject) => {
if (criteria) {
result.children = []
const actions = result
.map(item => item.element)
.map(dbCallToGetChildren)
Promise.all(actions).then(children => { // returns a promise
result.children.push(...children)
return resolve("successfully is processed!")
})
}
reject("invalid criteria!")
})
}