1

I've the following code which works, I currently configure eslint and got following error

1. ESLint: iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations. (no-restricted-syntax)

2. ESLint: Unexpected `await` inside a loop. (no-await-in-loop)

The idea of the code is following:

  1. loop on global accounts which contain list of accounts (first for)

  2. prepare request for eu region

  3. prepare request for us region

  4. run async request to get the users from EU

  5. loop on the value and if find url return 6 - 7 same as 4-5 but for US region

     async function acount(global) {
    
         // here i got the first eslint error iterators/generators
         for (const account of global) {
    
              // create http request for getting the users - region EU
             let usersEUReq = getUsers(account.guid, region.1);
    
             // create http request for getting the users region US
             let usersUSReq = getUsers(account.guid, region.2);
    
             const usersEU = await axios(usersEUReq);
    
           // here I got the response from the promise and should loop on it got get URL
             for (const sub of usersEU.data) {
                 if (sub.url) {
                     return sub.url
                 }
             }
    
             const usersUS = await axios(usersUSBReq);
             for (const sub of usersUS.sub) {
                 if (sub.url) {
                     return sub.url
                 }
             }
     }
    

btw, I cannot use Promise.all or race as I need the code run for Eu and then US

Wyck
  • 10,311
  • 6
  • 39
  • 60
Jenny M
  • 923
  • 1
  • 14
  • 37
  • 3
    If these linting errors are a problem for you, then why do you have the `no-restricted-syntax` and `no-await-in-loop` rules enabled? Are you obligated to use these rules for some reason? – Jake Holzinger Aug 03 '20 at 21:47
  • 1
    @JakeHolzinger - I use the eslint best practice, didnt did anything special..., is there other way that I can write this code or should I simply ignore this rules? I dont want to write bed code... – Jenny M Aug 03 '20 at 21:56
  • 1
    linting rules are not hard and fast. They depend on circumstances. If they don't fit your situation, turn them off. – Quentin Aug 03 '20 at 22:04
  • If you *want* your loop to do the requests sequentially, then the *no-await-in-loop* rule has no place there. See its documentation - you'll need to turn it off for all the false positives it produces. – Bergi Aug 03 '20 at 22:07
  • You can do a Promise.all where each item is an async function that does the body of the loop. i.e. try to write a `foreachasync` function so that the accounts can be processed in any order, but the EU, then US axios requests happens serially for each account. – Wyck Aug 04 '20 at 00:00
  • What do you mean when you are saying the code works? From what I can read it might be functioning, but it doesn't do what you are saying it is supposed to do – Icepickle Aug 04 '20 at 10:06

1 Answers1

1

Unless you explicitly want to serially loop over the awaited promises, you should use Promise.all or Promise.race (or Promise.any() when all major browsers support it). They will run your promises at the same time.

For example:

function getuserdata(account) {
    return [region.1, region.2].map(_region => getUsers(account.guid, _region)).map(axios);
}

async function acount(global) {
    let userdata = await Promise.all(global.flatMap(getuserdata))
    for (const sub of userdata) {
        if (sub.url) {
            return sub.url
        }
    }
}

If you really do want to do a serial loop, then what you have will work.

Kvothe
  • 386
  • 2
  • 8
  • Thanks I know about the promise.all I cannot use it in my case as I need to run one request and then the other one , if I cannot use promise.all and race which option do I have to write the code better?\ – Jenny M Aug 03 '20 at 21:59
  • And how the second option you give will emit the eslint errors? – Jenny M Aug 03 '20 at 22:01
  • You should probably just disable that linting setting then. It's mostly there so people don't fall into the "noob trap" of looping over promises rather than running them concurrently. – Kvothe Aug 03 '20 at 22:04
  • 1
    +1 for the first part of the answer, [-1 for the second](https://stackoverflow.com/q/37576685/1048572). – Bergi Aug 03 '20 at 22:05
  • @Kvothe The OP's original for..of code works but your forEach code is broken and does not work as expected because none of the Array methods forEach, map, filter, reduce etc. works with async/await – slebetman Aug 03 '20 at 22:47
  • 1
    The `.forEach()` loop does not work properly with `await` and will NOT run them serially because `.forEach()` is not promise-aware. What you show also won't even run because the callback would have to be `async` for you to be able to use `await`, but if you fix that, it will run, but not run serially. It will run them all at once. To use `await` in a loop, use a regular `for` loop, not `.forEach`. – jfriend00 Aug 03 '20 at 23:21
  • 1
    Thanks, i've just removed it because that's basically what the OP has. – Kvothe Aug 03 '20 at 23:36