Skip to content

Instantly share code, notes, and snippets.

@evocateur
Last active August 29, 2015 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save evocateur/3b02824bc181ec8f8eb2 to your computer and use it in GitHub Desktop.
Save evocateur/3b02824bc181ec8f8eb2 to your computer and use it in GitHub Desktop.
Y.Promise.each
YUI.add('promise-each', function (Y) {
function isArray(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
function isFunction(obj) {
return obj && (typeof obj === 'function');
}
Y.Promise.each = function (values, fn, context) {
var Promise = this;
// down the rabbit hole...
return new Promise(function (resolve, reject) {
if (!isArray(values)) {
reject(new TypeError('Promise.each expects an array of values or promises'));
return;
}
if (!isFunction(fn)) {
reject(new TypeError('Promise.each expects an iterator function'));
return;
}
var i = 0,
length = values.length,
remain = length,
result = [],
chains;
function chain(index) {
return Promise.resolve(values[index])
.then(function (value) {
// cache resolved value for final resolution
result[index] = value;
// call iterator without caching return values
fn.call(context, value, index, values);
if (--remain === 0) {
resolve(result);
}
}, reject) // reject when promise rejects
.catch(reject); // reject when iterator throws
}
if (length < 1) {
return resolve(result);
}
// start chain with first value
chains = chain(i++);
// chain the rest of the values
for (; i < length; i++) {
chains = chains.then(chain(i), reject);
}
});
};
}, '', { requires: ['promise'] });
YUI({
modules: {
'promise-each': {
fullpath: './promise-each.js',
requires: ['promise']
}
}
}).use('promise-each', function (Y) {
Y.Promise.each(['foo', 'bar', Y.when('teapot'), 'baz'], function (val, idx) {
if (idx === 1) {
throw new Error('threw at index 1');
}
Y.log('"' + val + '" at index %d' + idx);
})
.then(function (result) {
Y.log(result);
})
.catch(function (ex) {
Y.error(ex);
});
});
#!/usr/bin/env node
var path = require('path');
var YUI = require('yui').YUI;
var Y = YUI({
useSync: true,
modules: {
'promise-each': {
fullpath: path.join(__dirname, 'promise-each.js'),
requires: ['promise']
}
}
}).use('promise-each');
Y.Promise.each(['foo', 'bar', Y.when('teapot'), 'baz'], function (val, idx) {
if (idx === 1) {
throw new Error('BOOM at index 1');
}
console.log('"%s" at index %d', val, idx);
})
.then(function (result) {
console.log('result', result);
})
.catch(function (ex) {
console.error(ex);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment