0

Goal is to push sampled data, as an object, onto an array, at a periodic interval and wait to log the new array out to the console once it is finalized.

I'm new to JS, so take it easy ;). I am likely making this more complicated than it needs to be. Thought it would be as simple as a setTimeout() in a for loop.

I have been able to generate the array two different ways, using IIFE with a setTimeout() also the setInterval() below. Not sure how to get the async await function working with an array push() method querying length. Maybe this is not a good approach?


class Sample {
    constructor(tag, timeStamp) {
        this.tag = tag;
        this.timeStamp = Date.now();
    }
}

function arrayGenerator(tag){
    return sampleArr.push(new Sample(tag));
};

function setIntSample(callback, delay, iterations) {
    var i = 0;
    var intervalID = setInterval(function () {
       callback(i);
       if (++i === iterations) {
           clearInterval(intervalID);
       }
    }, delay);
};

Above seems to work console.log()-ing the array as it is generated in the arrayGenerator() function. Below, no dice

function resolveAfterArrGeneration(){
    return new Promise(resolve => {
        arrLength = setIntSample(i => {arrayGenerator(i)}, 3000, 5) 
        if (arrLength === 5) {resolve();}
    });
}

async function ans() {
    var answer = await resolveAfterArrGeneration();
    console.log(sampleArr);
}
ans();

3 Answers 3

1

The basic idea is to return a promise and resolve the promise when the setInterval has run enough iterations. You can do that in a single function with something like this (with extra console.logs to show the process):

class Sample {
    constructor(tag, timeStamp) {
        this.tag = tag;
        this.timeStamp = Date.now();
    }
}

function makeSamples(iterations, delay){
    let samples = [], i = 0;
    return new Promise(resolve => {
        let intervalID = setInterval(function () {
           console.log("pushing new sample")
           samples.push(new Sample('tag: ' + i));
           if (++i === iterations) {
               console.log("finished resolving")
               clearInterval(intervalID);
               resolve(samples)
           }
        }, delay);
    })
}

makeSamples(5, 1000).then(console.log)

Sign up to request clarification or add additional context in comments.

Comments

0

I would isolate the delay part (the asynchronous) part and create a separate, generic function delay() for that. All the rest becomes simple then, using an async function and for loop:

const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));

class Sample {
    constructor(tag, timeStamp) {
        this.tag = tag;
        this.timeStamp = Date.now();
    }
}

async function setIntSample(callback, ms, iterations) {
    const arr = [];
    for (let i = 0; i < iterations; i++) {
       if (i) await delay(ms); // don't delay first time
       arr.push(callback(i));
    }
    return arr;
}

const newSample = (tag) => new Sample(tag)

console.log("wait for it....");
setIntSample(newSample, 1000, 5).then(console.log);

1 Comment

Much appreciated. Looks like this would make it simple to run multiple processes in parallel at different sampling frequencies.
0

Another way I just got working with a generator function

function* simpleGenerator(){
    var index = 0;
    while (true)
        yield {tag: index++, time: Date.now()} 
}
var gen = simpleGenerator();

..with the corresponding push

        arr.push(gen.next().value);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.