Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support promises #19

Open
TwitchBronBron opened this issue Jan 17, 2019 · 7 comments
Open

Support promises #19

TwitchBronBron opened this issue Jan 17, 2019 · 7 comments

Comments

@TwitchBronBron
Copy link

TwitchBronBron commented Jan 17, 2019

It would be great if node-glob-all returned a promise for those of us who are moving away from the node callback model. Since nobody is expecting a return value from globAll, I would imagine this would be a pretty safe change to implement.

I'm willing to do the work if you're interested in accepting the pull request.

I noticed that globAll returns the GlobAll instance, but this is undocumented. So with the assumption that nobody should actually be using the returned instance of GlobAll, this code would do the trick (untested):

var globAll = function (array, opts, callback) {
    return new Promise(function (resolve, reject) {
        var g = new GlobAll(false, array, opts, function (error, results) {
            if (error) {
                reject(error);
                return (typeof callback === "function") ? callback(error) : null;
            } else {
                resolve(results);
                return (typeof callback === "function") ? callback(null, results) : null;
            }
        });
        g.run(); //async, so results are empty
    });
};

If you must continue to return that GlobAll instance, then perhaps something like this would work, where it keeps the existing functionality, and only returns a promise when you do not provide a callback.

var globAll = function (array, opts, callback) {
    if (callback) {
        var g = new GlobAll(false, array, opts, callback);
        g.run(); //async, so results are empty
        return g;
    } else {
        return new Promise(function (resolve, reject) {
            var g = new GlobAll(false, array, opts, function (err, results) {
                if (err) {
                    reject(error);
                } else {
                    resolve(results);
                }
            });
            g.run(); //async, so results are empty
        });
    }
};

Usage

//since we didn't provide the callback parameter, globAll returns a promise
globAll('someGlob').then(function (results) {
    //do something on success
}, function () { 
    //do something on error
});
@TwitchBronBron
Copy link
Author

@jpillora any thoughts on this?

@jpillora
Copy link
Owner

jpillora commented Oct 7, 2019

Hey Bronley, 9 months! Very patient :)

I wonder if the GlobAll instance could extend Promise, and maintain existing functionality (emitting match and end events)?

Otherwise I’m happy to change the return value to a Promise and bump the major version of this package👍

PR away!

@TwitchBronBron
Copy link
Author

So, another 7 months have passed. I ended up switching glob libraries for a different reason for that project, but I'm back now because I need it for a new project :D

I'm going to put together a PR for this with the GlobAll instance extending promise like you suggested. But before I do that, I wanted to verify with you are ok with requiring that glob-all depends on Promise existing? Because once we use Promise as the inheriting prototype, GlobAll will throw exceptions if Promise doesn't exist (i.e. I think NodeJS started supporting promises around 0.12). This is probably not an issue, but just wanted to verify.

If that concerns you, we could probably do something like this instead, which defers the promise usage to only once actually requested:

Object.defineProperty(GlobAll.prototype, 'promise', {
    get(){
       if('undefined' === typeof Promise){
            throw new Error('Promise is not supported in your environment');
        } else{
              //return the promise instance somehow
        }
    }
});

By doing this, we could allow glob-all to still work the same in all environments, and upgrade to using promises only when explicitly requested.

var g = globAll(...);
var result = await g.promise;

Thoughts?

@TwitchBronBron
Copy link
Author

@jpillora what do you think of this approach?

@TwitchBronBron
Copy link
Author

@jpillora thoughts on my proposal?

@GeorgeTaveras1231
Copy link

glob@^9 supports promises and array of globs. Since this library is based on glob, maybe it makes sense to deprecate this library? 🤔

@TwitchBronBron
Copy link
Author

Yeah, I think that makes sense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants