1

let object = [
  {
    id: '01',
    name: 'Subject',
    'Data.type': 'maths',
  },
  {
    id: '02',
    name: 'Subject',
    'Data.type': 'science',
  },
  {
    id: '04',
    name: 'language',
    'Data.type': 'node',
  },
  {
    id: '05',
    name: 'language',
    'Data.type': 'node',
  }
  /*...*/
];

let type=[];
let result=[];
object.map(async (value) => {
  type.push(value["Data.type"]);
  if(some condition){
  // 1st condition
   if(some condition){
    // 2nd condition
     if(some condition){
      let path= await functionName();
      // 3rd conditon
      if(some condtion){
      // 4th condition
      result.push("task");
     }
    }
   }
  }
  // I can fetch result till here console.log(result)
});
// i can't fetch result here and i can't put condtion here as data present inside dObject is dummy for refrence purpose only
console.log(type);
console.log(result);

I declare two array outside the map function i can fetch name array easily but can't fetch result array i don't know why but its scope get ended inside the map function is there any other way i can fetch result outside the map function

  • for reference i am posting my name function which work fine

let object = [
  {
    id: '01',
    name: 'Subject',
    'Data.type': 'maths',
  },
  {
    id: '02',
    name: 'Subject',
    'Data.type': 'science',
  },
  {
    id: '04',
    name: 'language',
    'Data.type': 'node',
  },
  {
    id: '05',
    name: 'language',
    'Data.type': 'node',
  }
];

let type=[];
let result=[];
object.map(async (value) => {
  type.push(value["Data.type"]);
});
// i can't fetch result here and i can't put condtion here as data present inside dObject is dummy for refrence purpose only
console.log(type);
console.log(result);

here i can fetch my type array which i have declare perfectly but in 1st snippet i can't fetch result outside the map function

  • as i wrote my condition perfectly that's why its running perfectly inside map function but not outside the map function
6
  • Try using var instead of let. Because var is function scoped and let is block scoped. Commented Jun 4, 2021 at 5:38
  • If you're using asynchronous code inside the loop (which I'm guessing you are), then please show the ACTUAL asynchronous code because that would be a major part of the issue. Commented Jun 4, 2021 at 5:47
  • yes there is object.map(async (value)=>{ //rest code here}); @jfriend00 i am doing like this Commented Jun 4, 2021 at 5:48
  • Snippet 1 and snippet 2 looks the same to me (except all of the conditions in snippet 1.) What is the difference? Commented Jun 4, 2021 at 5:50
  • 2
    Well .map() is NOT async aware. It doesn't pause the loop to wait for your await so you end up trying to use the array BEFORE anything has been pushed into it. You can either use await Promise.all() on the resulting array of promises that your .map() returns or you can switch to a for loop which IS async aware and will pause the loop for your await. Commented Jun 4, 2021 at 5:51

1 Answer 1

2

Well .map() is NOT async aware. It doesn't pause the loop to wait for your await so you end up trying to use the array BEFORE anything has been pushed into it by your asynchronous operations. This is a timing issue.

You can either use await Promise.all() on the resulting array of promises that your .map() returns or you can switch to a for loop which IS async aware and will pause the loop for your await.

FYI, you should never use .map() if you're not interested in the resulting array that it returns as that's its entire point. There are more efficient ways to just iterate an array. And, when doing asynchronous things, a plain for loop is far, far, far more powerful these days with await since you get full control over the loop which .forEach() and .map() do not offer since they are not async aware.

You don't show much real code, but this would be the general idea with a for loop:

async someFunction() {

    let type=[];
    let result=[];
    for (let value of object) {
      type.push(value["Data.type"]);
      if(some condition){
      // 1st condition
       if(some condition){
        // 2nd condition
         if(some condition){
          let path= await functionName();
          // 3rd conditon
          if(some condtion){
          // 4th condition
          result.push("task");
         }
        }
       }
      }
    }
    console.log(result);
}

someFunction().then(() => {
    console.log("all done");
}).catch(err => {
    console.log(err);
});
Sign up to request clarification or add additional context in comments.

5 Comments

as i am using let path = await functionName() in side for (let value of object) {} its showing me await only valid with async function
@Vikas - Yes, the parent function needs to be async. That's the same for any function you use await in. You don't show that function. If there isn't a parent function, then you just need to put this code in an async function and then call it.
yes got it where i was doing mistake thank you @jfriend00
just for curiosity how will code look like if i am using await Promise.all() do i have to write like this let path =await Promise.all(functionName()); ?
@Vikas - It depends upon your real code, but await Promise.all(object.map(async value => {...})) would tell you when all the iterations of the loop were done. If you actually return a value from the .map() callback, then you can accumulate the values directly and in order with let results = await Promise.all(object.map(async value => {... return someValue;})). This will attempt to run all your asynchronous operations in parallel (which has pros and cons).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.