FredFloete
FredFloete

Reputation: 659

Array.every() - Return in callback possible?

I'm parsing an input file and run over every element with the Array.every function. Depending on the structure, a manual input of the user is needed. So if you have for example something like this:

configData.users.every(function(user){
 if(user.enabled == 1){
    if(user.mobile == 1){
        prompt.start();
        prompt.get(['mCode'], function (err, result) {
         //Do something...
         //return needed here!
        });
    }else{
        //Do something else...
        return true;
    }
 }
});

So in my case prompt is calling a callback function when the input by the user is typed in. At this point where are clear and the next element can be handled. So how can I call return at this point to continue the every() function?

Thanks for you help.

Upvotes: 2

Views: 501

Answers (2)

oshnaps
oshnaps

Reputation: 408

Well, I'm pretty sure about my answer - if the link to the other question doesn't help - I'll adapt it to your specific problem (I use 'when', you can use your preferred promises package):

configData.users.reduce(function(lastValue, user){
    return lastValue.then(function(u) {
        if (user.enabled == 1) {
            if (user.mobile == 1) {
                prompt.start();
                return when.promise(function(resolve, reject) {
                    prompt.get(['mCode'], function (err, result) {
                        //Do something...
                        //return needed here!
                        resolve(u);
                    });
                });
            } else {
                //Do something else...
                return when.resolve(u);
            }
        }
    });
}, when.resolve(configData.users[0]));

reduce is not only to sum entries, the thing about it is that you can use the last value you got in the function (that belongs in some matter to the last array entry) for the next value. I claim that's what you need because you want to return a promise (in order to wait for things to happen in your callback).

I tested it and it works as I understand you need it to work, hope I didn't miss your intention in the question. Right now the code is going over the first user twice, you should slice the array or something to make it work exactly as you wish.

Notice that right now you return nothing on user.enabled == 0, you'll probably want to add another else to continue the reduce flow as wanted.

Upvotes: 1

user663031
user663031

Reputation:

You cannot execute asynchronous things synchronously, which is essentially what you are trying to do. As mentioned in comments, promises are the best way to go. If you want to write it directly, the simplest approach is:

function handle_users(users) {
  var i = 0;
  function _internal() {
    if (i >= users.length) return;
    var user = users[i];
    if (user.enabled == 1) {
      if (user.mobile == 1) {
        prompt.start();
        prompt.get(['mCode'], function (err, result) {
          //Do something...
          //return needed here!
          i++;
          _internal();
        });
      } else {
        i++; 
        _internal();
        return true;
      }
   }
   internal();
}

We define an internal function which we call in a sort of recursive way from within the callback on prompt.get.

If you want to get the information that all users have qualified or entered the correct keyword or whatever it is, then keep a boolean variable at the top level, set it to false when there is a failure, and then return it from where the function returns. Or if you want to stop processing at the first failure, as every does, you could check that at the top of _internal and return immediately.

Upvotes: 1

Related Questions