简体   繁体   中英

Cleaner way to wait for a promise to be resolved before assigning its value to an array of objects

I want to wait for a promise to be resolved before assigning its value to an object. I have some ideas on how to do this, doing the assignment inside of the .then for example, but I want to know what's the best practice.

Pseudo code:

orderData = [
    {
    'productId':'69',
    'name': 'honey'
    },
    {
    'productId':'96',
    'name': 'horse'
    }]

async function post(orderData){
    for (let i in orderData){

    //getting extra information about the products
        var productData = await axios.get('/' + $(orderData[i].product_id))
        .then(response => {return response})

        items[i] = {
        "product_code": orderData[i].product_id,
        "name": orderData[i].product_name,

        //does this work
        "cfop": await productData.cfop,
        "icms_situacao_tributaria": await productData.icms

items.[0].cfop or icms to not be null

You don't need the .then when using await . await waits for a promise to be resolved and then extracts the value from the promise. axios.get already returns a promise (based on the first example in the axios documentation ), so there is no reason to use .then .

Async/await is a newer and cleaner language feature allows promises to run in a synchronous manner, allowing you to replace .then and .catch . You should not be using .then inside your async function. Take a look at this short example from Google for more info on how async/await cleans up regular promise code.

Removing .then(response => {return response}) has the same output.

var productData = await axios.get('/' + $(orderData[i].product_id));

Either awaiting or assigning within the promise chain will work, mostly depends how you need to use promise results, what variables in scope, etc... Here's a source I found helpful when first learning the subtle differences between async/await , Promises, and try/catch , and how they work together.

async function post(orderData) {
  const items = [];
  for (let i in orderData){

    //getting extra information about the products
    var productData = await axios.get('/' + $(orderData[i].product_id));

    items.push({
      "product_code": orderData[i].product_id,
      "name": orderData[i].product_name,
      "cfop": productData.cfop, // no need to await here, you have the resolved value
      "icms_situacao_tributaria": productData.icms,
      ...
    });
  ...
}

or

async function post(orderData) {
  const items = [];
  for (let i in orderData){
    await axios.get('/' + $(orderData[i].product_id));
      .then(productData => {
        items.push({
          "product_code": orderData[i].product_id,
          "name": orderData[i].product_name,
          "cfop": productData.cfop, // no need to await here, you have the resolved value
          "icms_situacao_tributaria": productData.icms,
          ...
        });
      });
  ...
}

or using map

function post(orderData) {
  return orderData.map(async (data) => {
    return await axios.get('/' + $(data.product_id));
      .then(productData => ({
          "product_code": data.product_id,
          "name": data.product_name,
          "cfop": productData.cfop, // no need to await here, you have the resolved value
          "icms_situacao_tributaria": productData.icms,
          ...
        });
      );
  });

  ...
}

 const axios = { get: (p) => Promise.resolve({ data: { cfop: 42, icms: 42 } }) } const Axios = { all: (p) => Promise.all(p) } // above is for the purpose of the demo const orderData = [ { 'productId': '69', 'name': 'honey' }, { 'productId': '96', 'name': 'horse' } ]; function getProduct({ name, productId }) { return axios.get(`/${productId}`).then(res => ({ "product_code": productId, "name": name, "cfop": res.data.cfop, "icms_situacao_tributaria": res.data.icms })); } async function post(orderData) { console.log({ items: await Axios.all(orderData.map(getProduct)) }); } post(orderData) 

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