如何在Javascript中将Promises与async和await一起使用



我有一个方法,它返回所有对象的JSON

const getAllItems=async function(req,res){
localDB.find({
selector:{type:'item'},
fields: ['_id', 'itemNumber','itemName',"compatablities","companyID"],
sort: ['_id']
}).then(async function (result) {
if (result) {
var refinedResult=[]
//console.log(result.docs[0]);
for (i = 0; i < result.docs.length; i++) {
var parentItem={
itemName:result.docs[i].itemName,
itemNumber:result.docs[i].itemNumber,
companyID:result.docs[i].companyID,
parentItemNo:"Parent"
}
console.log("before");
const resolvedN=await resolveName(parentItem.companyID);
console.log(resolvedN)
console.log("Passed");
refinedResult.push(parentItem);
for (j = 0; j < result.docs[i].compatablities.length || 0; j++) {
var oneCompatItemConstruct={
itemName:result.docs[i].itemName,
itemNumber:result.docs[i].compatablities[j].itemNumber,
companyID:result.docs[i].compatablities[j].companyID,
parentItemNo:result.docs[i].itemNumber,
}
//console.log(oneCompatItemConstruct);
refinedResult.push(oneCompatItemConstruct);
}
}
return res.status(200).json({
refinedResult
})
}
}).catch(function (err) {
console.log(err);
})
}

并且对象具有要解析为名称的ID,因此我写了一个函数来解析它的名称,并将cid作为参数,并返回一个字符串

function resolveName(c_id){
localDB.find({
selector:{type:'company',_id:c_id},
fields: ['companyName'],
})
.then(company=>{
if (company.docs.length >=1) {
console.log(c_id);
const result = company.docs[0].companyName
return result
}
else{
return null
}}).catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
}

我希望在每个循环中调用该函数,并在执行时更新代码我会那样做吗?

只需将函数包装在Promise中,并使用resolvereject:返回值

function resolveName(c_id) {
return new Promise((resolve, reject) => {
localDB.find({
selector: { type:'company', _id:c_id },
fields: ['companyName'],
})
.then(company=> {
if (company.docs.length >= 1) {
console.log(c_id);
const result = company.docs[0].companyName
resolve(result)
}
else {
resolve(null)
}
})
.catch(err => {
reject(err);
res.status(500).json({
error: err
});
});
});
}

它可能看起来像这样。

您的代码在每个入站请求中发送多个异步请求。从性能的角度来看,这些应该并行进行:不应该简单地等待每个请求返回,然后再发出下一个请求。这就是我在解决方案中使用Promise.all的原因。

请注意,我可以看到您的代码中至少有一个逻辑问题,我无法纠正。

const getAllItemsQuery = {
selector: { type: 'item' },
fields: ['_id', 'itemNumber', 'itemName', "compatablities", "companyID"],
sort: ['_id']
}
const getAllItems = async function(req, res) {
const { docs } = await localDB.find(getAllItemsQuery)
if (!docs) return
const promises = docs.map((doc) => createRefinedResultForDoc(doc))
return res.status(200).json({ refinedResult: (await Promise.all(promises)).flat() })
}
async function createRefinedResultForDoc({ itemName, itemNumber, companyID, compatibilities }) {
const result =  [ { itemName, itemNumber, companyID, parentItemNo: "Parent" } ]         
const resolvedN = await resolveName(companyID)
// use resolvedN...
compatibilities.forEach((compatibility) => {
result.push({
itemName,
itemNumber: compatibility.itemNumber,
companyID: compatibility.companyID,
parentItemNo: itemNumber,
}))
return result
}
const createResolveNameQuery = (_id) => ({
selector: { type: 'company', _id },
fields: ['companyName'],
})
const resolveName = async(c_id) => {
const { docs: [ doc ] } = await localDB.find(createResolveNameQuery(c_id))
if (!doc) throw 'name not resolved'
console.log(c_id)
return doc.companyName
}

最新更新