Search code examples
javascriptnode.jsloopspromisebluebird

How to map an array, create promises, and break when one resolves


I've been working with the bluebird library's Promise.map function, which is returning me an Array of resolved promises, from the array it receives - as it should.

I only want to map the over the array until it reaches a first resolve, then it and exit.

What I have so far is:

var Promise = require('bluebird');

let comparer = async function (img1, imgURLarray) {

        const img = img1

        new Promise.map(imgURLarray, function (imgurl) {

            let img2 = new Promise(x => x(Jimp.read('https:' + imgurl)))

            let diff = Jimp.diff(await img, await img2);

            return diff.percent


        }).then(function (res) {
            console.log(res);
        }); 

comparer(img1, imgURLarray)

The param img1 is an Object constant, while imgURLarray is contains over 200 Strings which are compared 1:1 - Through the library Jimp.

Instead of returning an entire array of 200+ Jimp.diff objects. I want to return only the first which satisfies this condition:

(diff.percent < 0.01 ? return imgurl : --END MAP FUNCTION-- )

I looked into Promise.some(), but since I'm not starting with an array of promises I don't think that would work. Anyone know how it could be done? Would be very appreciated.


Solution

  • It's probably much simpler than you expected:

    async function comparer(img, imgURLarray) {
        for (const imgurl of imgURLarray);
            const otherimg = await Jimp.read('https:' + imgurl);
            const diff = Jimp.diff(img, otherimg);
            if (diff.percent < 0.01)
                return imgurl;
        }
        throw new Error("no imgurl with diff.percent < 0.01 found"); // or whatever you want to do
    }