简体   繁体   中英

JavaScript - Async/Await - How to Return result from nested functions?

I'm new to Node.js and having difficulty working with async/await model. The issue I'm having is with nested function calls returning data in an async/await method, I always get 'undefined' . My functions structure is like this:

const findCustomerOrder = async (id) => {
    const orders = await Order.find({custoemrId:id})
        .then(async (order) => {
            if(order)
                {
                  const products = await findProductsByOrderId(order._id)
                        .then(async (result) => {
                            for(const r in result){
                                console.log("Product ID: ", result._id);
                            }
                        });
                }
            else
                console.log("order not found");     

        });
}

const findProductsByOrderId = async (id) => {
    try{
        const products = await Products.find({orderId:id}, (error, data) => {
            if(error) console.log(error);
            else 
                return data;
        });
    }
    catch(err){
            return 'error!!';
    }
}

I understand that if the top-level call is async/await then all the nested calls should be awaited as well that I've tried to do.

What am I doing wrong here?

Get rid of all the then , and also of the callback in the DB query. Use only await . It will make the whole code a lot easier to reason about and it should also solve your issue as part of the restructuring.

In the example below I also added a loop over the orders, because you are fetching all orders, as array, but then your code was behaving as if it got only one. I also fixed the products loop.

However, the way you fetch products doesn't seem to be right anyway, see my comment below. I didn't fix it because I don't know how your database structure looks, so I don't know what the right way would be.

async function findCustomerOrder (id) {
  const orders = await Order.find({ customerId: id })
  
  for (const order of orders) {
    console.log(`Order ID: ${order._id}`)
    
    const products = await findProductsByOrderId(order._id)
    for (const product of products) {
      console.log(`Product ID: ${product._id}`);
    }
  }
}

async function findProductsByOrderId (id) {
  // Note: I don't think this is right. It seems to find all
  // products with the given ID - which will always be one -
  // and that ID would be the _product_ ID and not the order ID.
  return await Products.find({ _id: id })
}

Preemptive comment reply: The return await is intentional, and this is why .

You should remove the then and also the callback and you can do something like below

 const findCustomerOrder = async(id) => { try { const orders = await Order.find({ custoemrId: id }); if (orders) { let promiseArray = []; orders.forEach(order => { promiseArray.push(findProductsByOrderId(order._id)); }); let results = await Promise.all(promiseArray); return results; } return "order not found"; } catch (err) { throw err; } } const findProductsByOrderId = async(id) => { try { const products = await Products.find({ _id: id }); return products; } catch (err) { throw err; } }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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