1

I'm very new to nodejs and I am trying to create an interactive shell script that will reply posts on my facebook wall. The problem is when I'm using the Readline module inside a loop, it's not stoping and just continue to loop.

Here's my whole code

var access_token = 'XXX';
var myId = 'XXX';
var FB = require('fb');
var url = require('url');
var utf8 = require('utf8');
var readline = require('readline');

var rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

FB.setAccessToken(access_token);
function getWallFeeds(feedLink, args) {
     FB.api(feedLink, 'get', args, function (res) {
        if (!res || res.error) {
            console.log(!res ? 'error occurred' : res.error);
            return;
        }

        processMessage(res.data);

        var nextLinkParts = url.parse(res.paging.next, true);

        var args = {
            limit: nextLinkParts.query.limit,
            until: nextLinkParts.query.until,
            access_token: nextLinkParts.query.access_token
        }
        getWallFeeds(feedLink, args);
    });
}

function processMessage(data) {
    for (i in data) {
        if (data[i].from.id!=myId) {
            name = data[i].from.name;
            message = data[i].message;
            post_id = data[i].id;
            console.log(post_id + ') ' + name+': '+utf8.encode(message));

            rl.question("Please enter you reply: \n\n", function(answer) {
                // Use answer and call FB api to post to comment..
                rl.close();
            });
        }
    }
}

feedLink = 'me/feed';
getWallFeeds(feedLink, {});

Here's the sample result

1020284792662_1020291351526) John: ....
Please enter you reply:

1020284792662_1020290585671) Ace: How are you!
Please enter you reply:

1020284792662_1020290581815) Nic: Hello there
Please enter you reply:
Fba Abugee
  • 73
  • 1
  • 9

3 Answers3

5

I already solved the problem, I used the module readline-sync. I spent 3 hours hunting for this answer.

Fba Abugee
  • 73
  • 1
  • 9
0

That is caused by nodejs asynchronous nature. You propably will have to build yourself some kind of queue that only prints a new question if the one before has been answered.

Propaply there are also modules doing the heavy lifting for you - did you already check this?

Cheers

Florian

Florian Loch
  • 809
  • 7
  • 12
  • 1
    [readline-sync](https://www.npmjs.org/package/readline-sync) solved my problem. thanks for the explanation. – Fba Abugee Nov 01 '14 at 08:26
0

It's because async nature of node.js

For loop dont wait until callback of rl.question is excecuted (because that callback is asynchronous) and iterates not caring about callback at all.

It's not only not waiting for callback, it also tend to pass value of last iteration to every callback - because often before any callback exectutes - iteration is finished and values are passed to callback as reference, so callback will have access to values from last iteration!

Additional info:

If You will use blocking (sync) modules, Your whole application will block. If its script, its ok, but if its web server - all clients will be blocked by every sync operation.

Generally - nodejs is "by default" asynchronous, and You have to learn it's implications to understand what Your code is doing. Its hardly possible to write sync-only code in nodejs.

here are some links to help You with that:
SO link
link 1
link 2
SO link 2

Community
  • 1
  • 1
Jarema
  • 3,291
  • 2
  • 17
  • 30