aframe
aframe

Reputation: 168

Delaying execution of an async messaging function in node.js

I have a series of lat/lng pairs that are returned from a decoded polyline.

Using forEach I extract each lat/lng pair and using pubnub.publish(), send this data to a channel.

pubnub.publish() is an async function and I need to delay the publishing of the message at each step through the forEach loop.

I have looked through a lot of answers on setTimeout executing immediately and tried different versions of the below, including, not wrapping the setTimeout in a closure, but am unable to delay the publish - it just sends them all as soon as it can.

Can anyone point out any glaring mistakes?

decodedPolyline.forEach(function (rawPoints) {

    var value = {
        lat: rawPoints[0],
        lng: rawPoints[1]
    };

    var sendmsg = function () {
        pubnub.publish({
            channel: id, 
            message: value,
            callback: function (confirmation) {
                console.log(confirmation);
            },
            error: function (puberror) {
                console.log('error: ' + puberror);
            }
        });
    };

    (function() {
        setTimeout(sendmsg, 2000);
    })();

    normalised.push(value);
});

Upvotes: 1

Views: 61

Answers (1)

taxicala
taxicala

Reputation: 21759

The forEach loop will be executed in near real time, meaning that all timeouts will finish almost exactly at the same time, you should increase the value of your timeout by 2000 in each iteration; Perhaps this works for you:

var sendmsg = function (value) {
    pubnub.publish({
        channel: id, 
        message: value,
        callback: function (confirmation) {
            console.log(confirmation);
        },
        error: function (puberror) {
            console.log('error: ' + puberror);
        }
    });
};

var timeoutVal = 2000;
decodedPolyline.forEach(function (rawPoints) {

    var value = {
        lat: rawPoints[0],
        lng: rawPoints[1]
    };

    (function(value) {
        setTimeout(function() {
            sendmsg(value);
        }, timeoutVal);
    })(value);

    //Add 2 seconds to the value so the next iteration the timeout will be executed 2 seconds after the previous one.
    timeoutVal = timeoutVal + 2000;

    normalised.push(value);
});

I've also moved the definition of the sendmsg function outside the loop. I believe it will be a little bit more performant if you dont define the function for each iteration. Hope this helps.

Upvotes: 2

Related Questions