Created
January 20, 2017 21:53
-
-
Save SaxxonPike/52bfc71bb91dcc0c896d8af64ed7044f to your computer and use it in GitHub Desktop.
"Must" promise addin
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (function(){ | |
| // --------------------------------------------------------------- | |
| // INITIALIZATION | |
| // --------------------------------------------------------------- | |
| // initialize library | |
| var lib = {}; | |
| if (window.Must) { | |
| lib = window.Must; | |
| } else { | |
| window.Must = lib; | |
| } | |
| // --------------------------------------------------------------- | |
| // UTILITY | |
| // --------------------------------------------------------------- | |
| // shallow clone object | |
| function clone(obj) { | |
| return merge({}, obj); | |
| } | |
| function curryXHR(method) { | |
| return function(url, options) { | |
| return executeEachXHR(url, merge({ method: method }, options)); | |
| }; | |
| } | |
| // execute XMLHttpRequest for each file | |
| function executeEachXHR(files, options) { | |
| if (files) { | |
| var promises = []; | |
| var opt; | |
| if (!isArray(files)) { | |
| opt = clone(options); | |
| opt.url = files; | |
| return executeXHR(opt); | |
| } else { | |
| for (var i in files) { | |
| opt = clone(options); | |
| opt.url = files[i]; | |
| promises.push(executeXHR(opt)); | |
| } | |
| return Promise.all(promises); | |
| } | |
| } else { | |
| return Promise.resolve([]); | |
| } | |
| } | |
| // execute XMLHttpRequest | |
| function executeXHR(options) { | |
| return new Promise(function(resolve, reject) { | |
| var xhr = new XMLHttpRequest(); | |
| var opt = options ? clone(options) : {}; | |
| var method = isolateOption(opt, "method"); | |
| var url = isolateOption(opt, "url"); | |
| var data = isolateOption(opt, "data"); | |
| xhr.open(method, url, true); | |
| merge(xhr, opt); | |
| xhr.onload = function(e) { | |
| if (this.status == 200) { | |
| resolve(this.response); | |
| } else { | |
| reject(Error(e.error)); | |
| } | |
| }; | |
| xhr.send(data); | |
| }); | |
| } | |
| // return whether or not the object is an array | |
| function isArray(v) { | |
| return v.constructor === Array; | |
| } | |
| // get value from hash and remove it if exists | |
| function isolateOption(options, key, defaultValue) { | |
| if (options) { | |
| var result = options[key]; | |
| delete options[key]; | |
| return result; | |
| } | |
| return defaultValue; | |
| } | |
| // return whether or not the object is a promise | |
| function isPromise(v) { | |
| return v.constructor === Promise; | |
| } | |
| // shallow merge two objects | |
| function merge(target, source) { | |
| source = source || {}; | |
| for (var i in source) { | |
| target[i] = source[i]; | |
| } | |
| return target; | |
| } | |
| // take a function and wrap it in a promise | |
| function promisify(f, data) { | |
| if (isPromise(f)) { | |
| return f; | |
| } else { | |
| return new Promise(function(resolve, reject) { | |
| try { | |
| var result = f(data); | |
| resolve(result); | |
| } catch(e) { | |
| reject(e); | |
| } | |
| }); | |
| } | |
| } | |
| // --------------------------------------------------------------- | |
| // INTERFACE | |
| // --------------------------------------------------------------- | |
| // perform async DELETE operation | |
| lib.delete = function(url, data) { | |
| return curryXHR("DELETE")(url, { data: data }); | |
| }; | |
| // pass-through | |
| lib.do = function(f, data) { | |
| return promisify(f, data); | |
| } | |
| // because English is fun | |
| lib.first = function(f, data) { | |
| return lib.do(f, data); | |
| } | |
| // perform async GET operation | |
| lib.get = function(url, data) { | |
| return curryXHR("GET")(url, { data: data }); | |
| }; | |
| // perform async GET operation and convert to JSON | |
| lib.getJson = function(url, data) { | |
| return lib.get(url, data).then(function(result) { | |
| if (isArray(result)) { | |
| return Promise.resolve(result.map(function(o) { JSON.parse(o); })); | |
| } else { | |
| return Promise.resolve(JSON.parse(result)); | |
| } | |
| }); | |
| }; | |
| // perform async PATCH operation | |
| lib.patch = function(url, data) { | |
| return curryXHR("PATCH")(url, { data: data }); | |
| }; | |
| // perform async POST operation | |
| lib.post = function(url, data) { | |
| return curryXHR("POST")(url, { data: data }); | |
| }; | |
| })(); |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Prerequisites
You will need a browser capable of supporting ES6 promises.
Click here to find out which browsers you can use.
Polyfill
If you need to get support for promises in an older browser (and
chances are you do), check out taylorhakes/promise-polyfill.
It's very small and compliments this library quite well.
Usage
Request a single file
With promises, there are no events to fiddle with.
Request multiple files
The results will be in the same order as the array you passed in
with the file names. Even if some of them finish loading out of
order.