0

i am trying to do a simple task. here is my function i am taking in a url link as parameters. i read the link, scrap it for data like title and headers. then i just try to store the data in mongo. for some reason looking at this code console prints y first and then x. why is javascript not compiling the code as it is written? any help on how i may be able to store this data in a global var. thanks i believe it is a call back error..

    insertNewItem(link){
    check(link, String);
    var xray = new Xray();

    var tname;
    xray(link, 'title')(function(err, title) {
                tname = title;
                console.log('x', tname);
        });

    var header;
    xray(link, 'h1')(function(err, h1) {
            header = h1;
        });

    console.log('y',tname);
    Items.insert({
        url: link,
        name: tname,
        bio: header
    });
}
  • As `x` is logged in a callback the order of execution completely depends on the implementation of the `Xray` object. That's the only meaningful thing anyone can say about this isolated piece of code. You should read up on how callbacks work and what asynchronous execution means. – Niels Keurentjes Nov 29 '16 at 00:48
  • thank you so much niel, makes alot of sense.. is there any way around my design i can accomplish my end goal here. bascially to store values in some variable and add it to the database. maybe create an external function that does the parsing and returns back values as arguments.. @NielsKeurentjes – ankibunkers Nov 29 '16 at 00:58

1 Answers1

0

Your code snippet is a bit short, but it appears that the function returned from xray executes its callback asynchronously. This means that your function will run to completion, then your callback (containing the console.log('x'...) will be executed.

This works much like setTimeout:

setTimeout(function() {
  console.log('a');
}, 1)
console.log('b');
// Prints b, a

Whenever you use an async callback, you must keep in mind that your code will not be executed top-to-bottom.

It takes a little to wrap you head around, but you catch on eventually.

In your case, you will probably want to do something like:

var tname;
var i = 0
xray(link, 'title')(function(err, title) {
  tname = title;
  console.log('x', tname);
  insert();
});

var header;
xray(link, 'h1')(function(err, h1) {
  header = h1;
  insert();
});

console.log('y', tname);

function insert() {
  if (i = 1) Items.insert({
    url: link,
    name: tname,
    bio: header
  });
  else i++;
}

That will start xray running, and call Items.insert when all the data is available. It would be a bit cleaner with promises, but that's a whole different subject.

RyanZim
  • 6,609
  • 1
  • 27
  • 43