1

I want to write a function to measure the performance of parts of code (other methods) that could return a value. This is what I came out at the moment:

const fn = async (): Promise<any> => {
    setTimeout(async (): Promise<any> => {
        return new Promise((resolve) => resolve('Hello World!'));
    }, 3000);
};

async measure(fn: () => Promise<any>): Promise<any> {
    const startTime = this.performance.now();
    const result = await functionToMeasure();
    const endTime = this.performance.now();

    const executionTime = endTime - startTime;
    console.log(`Executed in ${executionTime} ms`);

    return result;
}

const result = async measure(functionToMeasure); // result is undefined

The result is that functionToMeasure actually runs but it never returns something and at the moment I can use it only with void function.

I'd like to fix it if possible, or I can change completely if there's a better way to do it.

EDIT:

Actual code

const callback = async (): Promise<any> => {
    return await doSomethingAndReturn();
};
const searchResults: string[] = await measure(callback);

Do I've to wrap doSomethingAndReturn in an async Promise?

1
  • You should be wrapping the setTimeout in the Promise's executor function. At the moment you are wrapping the Promise inside of the setTimeout callback. See What is the JavaScript version of sleep()? Commented Dec 13, 2020 at 11:36

1 Answer 1

3

You need to wrap the setTimeout call in a promise and then resolve the result, so it should look something like this:

const {performance} = require('perf_hooks');

async function executeAndMeasure(fn) {
    const startTime = performance.now();
    const result = await fn();
    const endTime = performance.now();

    const executionTime = endTime - startTime;
    console.log(`Executed in ${executionTime} ms`);

    return result;
}

function someFnThatReturnsAPromise() {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve("Hello World");
        }, 3000);
    })
}

async function someAsyncFunction() {
    return 123;
}

(async () => {
    let result = await executeAndMeasure(someFnThatReturnsAPromise);
    console.log(`result was ${result}`);
    result = await executeAndMeasure(someAsyncFunction);
    console.log(`result was ${result}`);
})();
Sign up to request clarification or add additional context in comments.

4 Comments

It works! But just one more question: that code actually comes from my unit tests. So to call another async function, do I've to wrap it in a promise?
It it's already async, no. Defining a method async automatically returns the return value in a promise. See my edit.
I undestand. Is it easy to enable the measure function to call also callbacks with parameters?
Nowadays I'd always try to avoid callbacks as async/await allows for much cleaner code. If you really want to do it, you'd have to do the calculation for the executionTime in the callback.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.