Tirthankar Kundu
Tirthankar Kundu

Reputation: 705

accessing an array outside the function in node js

I know node.js run asynchronously, so outer functions execute earlier than the inner. But what is the way to access the notification array outside the for loop? I would like to access all the values in array at once, is this feasible?

var notification=[];

for(var j=0;j<6; j++)
{
     getNotification(response[j].sender_id,function(results)     // a function called
     {
         notification[j] =results;
         console.log(notification); // output: correct   
     });          
}
console.log(notification);       // output: [], need notification array values here

Upvotes: 3

Views: 3409

Answers (3)

MobA11y
MobA11y

Reputation: 18870

EDIT: If you don't want to use third party libs, this is how to do this in your own code.

/* jshint node:true*/


function getNotifications(responses, callbackToMainProgramLogic) {
    'use strict';
    var results = [];

    function getNotificationAsync(response) {
        getNotification(response.sender_id, function (data) {
            results.push(data);

            if (responses.length) {
                getNotificationAsync(responses.pop());//If there are still responses, launch another async getNotification.
            } else {
                callbackToMainProgramLogic(results);//IF there aren't we're done, and we return to main program flow
            }
        });
    }

    getNotificationAsync(responses.pop());
}

getNotifications(someArrayOfResonses, function (dataFromNotifications) {
    console.log('The collected data: ' + JSON.stringify(dataFromNotifications, 0, 4));
});

If you absolutely must, you could do something ridiculous like this. Your logic in the loopUntilDatReceived would be waiting for array sizes, not waiting for a non-empty string, but the idea is similar, and you shouldn't be using this anyway! :)

var fileData = '';
fs.readFile('blah.js', function (err, data) { //Async operation, similar to your issue.
    'use strict';
    fileData = data;
    console.log('The Data: ' + data);
});

function loopUntilDataReceived() {
    'use strict';
    process.nextTick(function () {//A straight while loop would block the event loop, so we do this once per loop around the event loop.  
        if (fileData === '') {
            console.log('No Data Yet');
            loopUntilDataReceived();
        } else {
            console.log('Finally: ' + fileData);
        }
    });
}

loopUntilDataReceived();

Did I mention this is ridiculous? Honestly, this is an awful idea, but it may help you understand what is going on and how the Node event loop works, and why what you want is not possible. AND why the other posts about callbacks, and flow control libraries are the way to go.

Upvotes: 1

frhd
frhd

Reputation: 10244

Send a callback to the notification loop like this:

var notification=[];

getNotificationArray( function() {
  console.log(notification);
});

function getNotificationArray (callback)
{
  for(var j=0;j<6; j++)
  {
    getNotification(response[j].sender_id,function(results)     // a function called
    {
      notification[j] =results;
      console.log(notification); // output: correct   
    });          
  }
  callback();
}

Upvotes: 0

amakhrov
amakhrov

Reputation: 3939

First off, you're having a closure issue in your code (please see the details here)

Then, you simply can't have the array values just next to the loop, because the values are not ready at this point. You need to wait until all 6 of your getNotification calls get resolved. You can do that with the async library. Something like:

var notification = [];

function createRequest (index) {
    return function (callback) {
        getNotification(response[index].sender_id, function(results) {
            notification[index] = results;
            callback(results);
        });
    }
}

var requests = [];
for(var j=0;j<6; j++) {
    requests.push(createRequest(j));
}

async.parallel(requests, function (allResults) {
    // notifications array is ready at this point
    // the data should also be available in the allResults array
    console.log(notifications);
});

Upvotes: 0

Related Questions