walmartlabs / little-loader

A lightweight, IE8+ JavaScript loader
MIT License
370 stars 28 forks source link

Documentation: Useful patterns around little-loader #20

Open ryan-roemer opened 8 years ago

ryan-roemer commented 8 years ago
exogen commented 8 years ago

Even if it's just "use async" with a quick snippet.

Many competing script loaders have a call signature like loadScript([script1, script2, script3, ...], callback). I don't think it's necessary to add to little-loader, but it means people are used to having a way to achieve that. (I personally don't like the at-a-glance ambiguity over whether calling with an array loads them in series or parallel, without consulting docs).

ryan-roemer commented 8 years ago

@exogen -- Added to list. I already have a todo in a project to actually do the parallel pattern in actual code!

pygy commented 8 years ago

Here's the Promise-based pattern we discussed on Reddit:

function swornLoad(resource, syncCB, context) {
    return new Promise(function(fulfill, reject) {
        _lload(resource, function(err){
            var res;
            if(typeof syncCB === 'function') try {
                res = syncCB.call(context, err);
            } catch (e) {
                reject(e)
            }
            if(err) {
                reject(err); // no-op if syncCB threw
            } else {
                fulfill(res);
            }
        });
    })
}

It allows to use promises for parallel loading while giving the opportunity to run code synchronoulsy on load.

Edit: From then on you can use Promise.all() for parallel loading, and

swornLoad('foo').then(function(){
    return swornLoad('bar')
}).then(function(){
  // do your thing
})

for sequential loading.

Both approaches can be trivially combined.

If you have a better name for the promisified _lload, I'm all ears, I don't like swornLoad much.

Edit again:

function sequentialLoad(ary) {
    return ary.reduce(function(acc, args) {
        if ({}.toString.call(args) !== '[object Array]') args = [args];
        return acc.then(function() { return swornLoad.apply(null, args) });
    }, new Promise(function(r){r()}));
}

where ary can hold strings or arrays to be applied to by swornLoad