Deba
Deba

Reputation: 989

How to return a Map of key value from a Promise call in javascript?

Hi I am new to NodeJs and Javascript. I have a requirement to return a Map of key value from a promise type call. I am calling NodeJs ping module where I want to make asynchronous call to ping the IP addresses and I want to store IP address as key and reachable status as value in a Map. My code is working where I am able to print in the console but I am not able to return a Map. I provide below the code. Please help me as I am struck now.

import { FileUtil } from "./util/file-util";
import ping = require("ping");

export class Test1 {

    public async pingManyIPAddress(): Promise<Map<string, boolean>> {
        let map: Map<string, boolean> = new Map();

        let fileUtil = new FileUtil();
        const fileNamePath: string = "testData/ipaddress-50.txt";
        const allIPs: string[] = await fileUtil.readFileLineByLineNonBlocking(fileNamePath);

        let cfg = {
            timeout: 10 // Timeout in seconds
        };

        allIPs.forEach(ip => {
            ping.promise.probe(ip, cfg).then((data: any) => {
                let ipAdrs = ip;
                let status = data.alive;
                console.log(ip,":",status); //Prints all IP and reachable status
                map.set(ip, status);
            });
        });

        // How to wait till the above promise line gets completely executed

        return Promise.resolve(map);
    }

    public async justCheck(): Promise<void> {
        let map: Map<string, boolean> = await this.pingManyIPAddress();        

        for (let key of Object.keys(map)) {
            console.log(key + " <-> " + map.get(key));//It does not print
        }
    }

}

let test2 = new Test1();
test2.justCheck();

Please guide me to learn so that I can modify the above code to return a Map.

Upvotes: 2

Views: 3155

Answers (1)

Nicholas Tower
Nicholas Tower

Reputation: 84957

Your pingManyIPAddress function is not waiting until it has the data. It will set up several calls to ping.promise.probe, but then it immediately moves on and returns Promise.resolve(map). The map is empty at this point, so any code that tries to use the map right away sees nothing in it.

You need to instead have it wait until those individual promises are complete. You can do this by making an array of promises, and combining them into one promise with Promise.all, then awaiting that.

public async pingManyIPAddress(): Promise<Map<string, boolean>> {
    let map: Map<string, boolean> = new Map();

    let fileUtil = new FileUtil();
    const fileNamePath: string = "testData/ipaddress-50.txt";
    const allIPs: string[] = await fileUtil.readFileLineByLineNonBlocking(fileNamePath);

    let cfg = {
        timeout: 10 // Timeout in seconds
    };

    const promises = allIPs.map(ip => {
        return ping.promise.probe(ip, cfg).then((data: any) => {
            let ipAdrs = ip;
            let status = data.alive;
            console.log(ip,":",status); //Prints all IP and reachable status
            map.set(ip, status);
        });
    });

    await Promise.all(promises);

    return map;
}

Upvotes: 2

Related Questions