繁体   English   中英

如何在 Javascript 中使用异步和等待的 Promises

[英]How to use Promises with async and await in Javascript

我有一个返回所有对象的 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
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM