Friday, 7 April 2017

In native node.js (v6.10.2), how to make for loops/forEach blocking async code

I have a "data" variable which is an array of JSON objects with the format

{ 
ap_name: blah,
switch_name:sw1, 
switch_ip:1.2.3.4
}

I want to transform the data variable to be an array of the following objects:

{
ap_name:blah,
switch_id:1
}

which is then pushed to ap_table in a database (I am using bookshelf.js as ORM)

By looking up in a database’s switch table for a particular switch_name & switch_ip, I can get the corresponding switch_id. If it isn’t there, I need to add a new entry to the switch table & return the corresposing switch_id.

I had coded the following:

await data.forEach(async function(i){
    console.log("fetching from switch table");
    var reqSwitch = await Switch.where({name:i.switch_name, ip:i.switch_ip}).fetch();
    if(!reqSwitch){
        console.log("Not present in switch table,adding a new Switch");
        var addSwitch = await Switch.forge({name:i.switch_name,ip:i.switch_ip,updated_by:user}).save({},{method:'insert'})
        if (!addSwitch){
            console.log("error in addSwitch");
        }else{
            console.log("Added new switch");
            console.log("addSwitch.get('id')",addSwitch.get('id'));
            i["switch_id"]=addSwitch.get('id');
        }
    }else{
        i["switch_id"]=reqSwitch.toJSON().id;
    }
    delete i.switch_ip;
    delete i.switch_name
});

console.log(“data”,data);

The above code is wrapped in an async function where other processing takes place as well.

I run the program with the following “data” object.

data [ { switch_ip: '2.3.4.5',
    switch_name: 'sw2',
    ap_name: 'a1'},
  { switch_ip: '2.3.4.5',
    switch_name: 'sw2',
    ap_name: 'a1' } ]

Before running, there is no switch with switch_ip: '2.3.4.5' & switch_name: 'sw2' in the switch table.

I get the following output:

fetching from switch table
fetching from switch table
data [ { switch_ip: '2.3.4.5',
    switch_name: 'sw2',
    serial_number: '',
    ap_name: 'a1'},
  { switch_ip: '2.3.4.5',
    switch_name: 'sw2',
    ap_name: 'a1' } ]
Try is fine
Not present in switch table,adding a new Switch
Not present in switch table,adding a new Switch
Added new switch
addSwitch.get('id') 36
Added new switch
addSwitch.get('id') 37

How can I make sure that

  1. A corresponding new switch is only added once. (i.e., forEach callback execution for each “i” in data, happens in series, one after the other)
  2. The “data” variable is printed only after the forEach is fully executed.

Would it be better if i used a for-loop or .map() function?



via acespade979

No comments:

Post a Comment