run (compiler, compilation, done) { return W.reduce(this.contentTypes, (m, ct) => { let id = ct.id let transformFn = ct.transform let options = Object.assign({ content_type: ct.id, include: 1 }, ct.filters) if (transformFn === true) transformFn = transform if (transformFn === false) transformFn = (x) => x return W(this.client.getEntries(options)) .then(response => { if(ct.ordered) { response.items = response.items[0].fields[Object.keys(response.items[0].fields)[0]] } return W.map(response.items, (entry) => transformFn(entry)) }) .tap((res) => { m[ct.name] = res }) .yield(m) }, {}).done((res) => { this.addDataTo = Object.assign(this.addDataTo, { contentful: res }) done() }, done) }
run (compiler, compilation, done) { return W.reduce(this.contentTypes, (m, ct) => { let contentTypeId let contentTypeOptions let transformFn if (typeof ct === 'string') { contentTypeId = ct contentTypeOptions = {} transformFn = true } else { contentTypeId = ct.id contentTypeOptions = ct transformFn = ct.transform } if (transformFn === true) transformFn = transform if (transformFn === false) transformFn = (entry) => entry return this.client.getEntries({content_type: contentTypeId}) .then((response) => {return W.map(response.items, transformFn)}) .then((result) => { m[contentTypeId] = result; return m; }) }, {}).done((res) => { this.addDataTo = Object.assign(this.addDataTo, {contentful: res}) done() }, done) }
run (compiler, compilation, done) { return W.reduce(this.contentTypes, (m, ct) => { let name let options let transformFn if (typeof ct === 'string') { name = ct options = {} transformFn = true } else { name = ct.name options = ct transformFn = ct.transform } if (transformFn === true) transformFn = transform if (transformFn === false) transformFn = (x) => x return this.client[name].get(options) .then((p) => { return W.map(p, transformFn) }) .tap((res) => { m[name] = res }) .yield(m) }, {}).done((res) => { // now we put the results on the data object this.addDataTo = Object.assign(this.addDataTo, { rooftop: res }) done() }, done) }
function mergeWorkItems(workItems) { return when.reduce( when.map(workItems, helpers.getWorkItems), function (arr, wi) { return arr.concat(wi); }, [] ); }
run(compilation, done) { // only pull data on the initial compile in watch mode if (this.addDataTo.contentful && !this.aggressiveRefresh) return done() return W.reduce( this.contentTypes, (m, ct) => { let transformFn = ct.transform let options = Object.assign( { content_type: ct.id, include: this.includeLevel }, ct.filters ) if (transformFn === false) transformFn = x => x return W(this.client.getEntries(options)) .then(response => { return W.map(response.items, entry => transformFn(entry)) }) .tap(res => { m[ct.name] = res }) .yield(m) }, {} ).done(res => { this.addDataTo = Object.assign(this.addDataTo, { contentful: res }) done() }, done) }
/** * Promise aware array iterator. Loops over elements of an array from left to right * applying the function to each element in the array. The function gets passed * the element and the index in the array. */ function each(array, fun) { return when.reduce(array, function (ignore, element, i) { return fun.call(undefined, element, i); }, null ); }
.then(function(list) { var subs = []; list.forEach(function(item) { subs.push(getChrootDiskUsage(path.join(loc, item))); }); if (subs.length) { return when.reduce(subs, function(sum, value) { return sum += value; }); } else return when.resolve(stats.size); });
.then( function( files ) { var promises = _.map( files, function( file ) { var relative = path.resolve( installed, file ); return { path: relative, stat: fs.statSync( relative ) }; } ); var directories = when.filter( promises, function( file ) { return file.stat.isDirectory(); } ); return when.reduce( directories, function( x, y ) { return x.concat( y.path ); }, [] ); } )
/** * Process the input through the function, return the output as a promise. * Accepts options, merged with constructor options with priority. * @param {String} input - a string of html to be processed * @param {Object} options - full options as in the constructor */ process (input, options = {}) { options = merge(this.options, this._validate(options)) options.PluginError = error.generatePluginError({ filename: options.filename, src: input }) let ast = options.parser(input, options.parserOptions) return W.reduce(options.plugins, (m, plugin) => plugin(m, options), ast) .then((output) => options.generator(output, options.generatorOptions)) .then((output) => { return Object.assign({output}, options) }) }
// Run resolvers on one path and return an object with the found path under a // key of the original path. // // Example: // resolving the path // 'a/file' // returns an object // {'a/file': {path: ['node_modules/a/file'], index: true}} function resolveOne(resolvers, context, path) { return when .reduce(resolvers, function(result, resolver) { return result ? result : resolver(context, path); }, undefined) .then(function(result) { result = typeof result === 'string' ? [result] : result; result = Array.isArray(result) ? {path: result, index: false} : result; var map = {}; map[path] = result; return map; }); }
return function (source, dest, data, type, api) { return when.reduce(strategies, function(result, strategy) { var strategyResult = strategy(source, dest, data, type, api); return api.isCanceled() ? when.reject(strategyResult) : strategyResult; }, data ).then(propagateSuccess, propagateSuccess); }
return when(this.getRentPayments()).then(function (rentPayments){ return when.reduce(rentPayments, function (tenants, rentPayment, index){ var tenantMatches = function (incoming, current, index, array){ return incoming.id === current.id; }; return when(rentPayment.getTenant()).then(function (tenant){ if (!tenants.some(tenantMatches.bind(tenantMatches, tenant))){ // Only add to array if tenant is not already in there return tenants.concat(tenant); } return tenants; }); }, []); });
.then(function(paths) { paths.forEach(styl.import.bind(styl)); paths.forEach(self.addDependency); var readFile = whenNodefn.lift(pathCacheHelpers.readFile); return when.reduce(paths, function(cache, filepath) { return readFile(filepath) .then(function(source) { return PathCache.createFromFile( pathCacheHelpers, cache, source.toString(), filepath ); }); }, { contexts: {}, sources: {}, imports: importsCache, }); })
/** * Promise aware array filter. Constructs an array of only the * elements of target array for which predicate resolves to a truthy * value. * * If the predicate rejects on any element then the whole operation rejects. * (i.e. rejections don't count as 'falsy' in this operation.) */ function filter(array, pred) { // console.log('entering filter '); return when.reduce(array, function (result, next) { // console.log('filtering '+JSON.stringify(result)+', '+next); return when(pred(next), function (isGood) { if (isGood) { // console.log('adding a good one: '+next); result.push(next); // } else { // console.log('skipping a bad one: '+next); } return result; }); }, [] ); }
function populateFeed(spotifyApi, user) { var promises = _.map(user.following, function(userId) { return spotifyApi.getUserPlaylists(userId, {limit: 42}).catch(function (err) { // We're to log this error but we may want to consider dropping the user in the future console.error('Failed to get playlists for:', userId, err); }); }); // Reset the user's feed as we are about to refill it user.feed = { data: [] }; // Run all the promises in parallel and return them all in one big array return when.reduce(promises, function(memo, playlists) { memo.feed.data = memo.feed.data.concat(_.map(playlists && playlists.items, pickPlaylistProperties)); return memo; }, user); }
exports.modifyNodes = function modifyNodes (tree, criteria, transform) { return when.reduce(tree, (m, node) => { // this will resolve immediately unless the node has children and needs to // recurse, in which case it will wait for the recursion to finish before // resolving let maybeRecurse = when.resolve() // bottom-up recurse if there is a tag with contents if (node.type === 'tag' && node.content) { maybeRecurse = modifyNodes(node.content, criteria, transform) .tap((content) => { node.content = content }) } // after the recurse has finished if applicable, test the node for the user // criteria and modify if applicable return maybeRecurse.then(() => { // run the criteria function (can be a promise) return when.resolve(criteria(node)).then((processNode) => { // if it doesn't match the criteria, move on if (!processNode) { m.push(node); return m } // if it does, run the user transform (can be a promise) return when.resolve(transform(node)).then((output) => { // push the output into the tree if it's a valid type if (Array.isArray(output)) { m.push(...output) } else if (typeof output === 'object') { m.push(output) } else if (!output) { // no node added } else { throw new UtilError('invalid replacement node', output) } return m }) }) }) }, []) }
return new Promise( ( resolve, reject ) => { spinner.text = `Getting statistics for ${ name }...`; const promises = versions.reduce( ( memo, version ) => { memo.push( getFile( `${ name }.js`, version, `vendor/${ name }-${ version }.js`, semver.lt( version, "16.0.0" ) ? `${ CDN_BASE }/${ name }/${ version }/${ name }.js` : `${ CDN_BASE }/${ name }/${ version }/cjs/${ name }.development.js`, spinner ) ); memo.push( getFile( `${ name }.min.js`, version, `vendor/${ name }-${ version }.min.js`, semver.lt( version, "16.0.0" ) ? `${ CDN_BASE }/${ name }/${ version }/${ name }.min.js` : `${ CDN_BASE }/${ name }/${ version }/cjs/${ name }.production.min.js`, spinner ) ); return memo; }, [] ); resolve( when.reduce( promises, ( memo, value ) => { memo.push( { name: value.name, version: value.version, path: value.path, url: value.url, size: value.body.length, sizeGzipped: value.body.length ? gzipSize.sync( value.body ) : 0 } ); return memo; }, [] ) ); } );
return all(args).then(function(args) { return when.reduce(tasks, function(arg, task) { return runTask(arg, task); }, args); });
return when(initialArg).then(function(arg) { return when.reduce(tasks, function(arg, task) { return runTask(arg, task); }, arg); });
return when.all(initialArgs).then(function(args) { return when.reduce(tasks, function(args, task) { return runTask(args, task); }, args); });
var x = when.reduce(filenames, function(prevPromise, filename, i) { console.log("Processing", i+1, "of", filenames.length, ":", filename); var newdirname = filename.replace( path.extname(filename), '' ); return fs.mkdir(newdirname).tap(function() { console.log("Directory created"); }).catch(function() { console.log("Directory already exists"); }).then(function() { return im.identify(filename); }).then(function(features) { console.log("Starting conversion"); var conversions = []; // Size is the larger dimension var size = Math.max(features.width, features.height); var zoomLevels = Math.floor(Math.log(size/256)/Math.log(2)); // Log base 2 of size/256 for (var i = 0; size > 256; i++, size = size / 2) { var factor = Math.pow(2, i); var numRows = Math.floor(features.height/(256 * factor) ); var paddedW = Math.ceil(features.width/(256 * factor)) * 256; var paddedH = Math.ceil(features.height/(256 * factor)) * 256; var cmd = [filename, '-background', 'none', '-gravity', 'southwest', '-resize', 100/factor + '%', '-extent', paddedW+'x'+paddedH+'!', '+repage', '-crop', '256x256', '-set', 'filename:tile', (zoomLevels-i+ZOOM_OFFSET)+'_%[fx:page.x/256]_%[fx:'+numRows+'-(page.y/256)]', '+repage', '-extent', '256x256', newdirname+'/%[filename:tile].png']; conversions.push(im.convert(cmd)); } return when.all(conversions); }).then(function() { console.log("Conversion finished"); return fs.readdir(newdirname); }).then(function(files) { var newfiles = files.map(function(n) { return path.join(newdirname, n.replace(/_/g, '/')); }); return when.all(newfiles.map(function(file) { return mkdirp( path.dirname(file) ); })).then(function() { return when.all(files.map(function(file, i) { var oldfile = path.join(newdirname, file); return fs.rename(oldfile, newfiles[i]); })); }); }).then(function () { console.log("Done!"); }); }, when.resolve(true));
function addExclamation(greeting) { return greeting + '!!!!!!'; } function handleError(e) { return 'drat!'; } // ---- SECOND EXAMPLE ---- var when = require('when'), rest = require('rest'); when.reduce(when.map(getRemoteNumberList(), times10), sum) .done(function(result) { console.log(result); }); function getRemoteNumberList() { // Get a remote array [1,2,3,4,5] return rest('http://example.com/numbers').then(JSON.parse); } function sum(x,y) { return x + y; }; function times10(x) { return x * 10; }; // ---- FROM ARTICLE ---- function finder(records) {
.then((ast) => W.reduce(opts.plugins, (m, plugin) => plugin(m, opts), ast))
.then(function(parents) { // find all the permissions for each parent and merge into one object return when.reduce(parents, this.reduceParentPermissions.bind(this, itemID), {}); }.bind(this));
.then(function () { // 串行 list 队列 return When.reduce(list, function (x, i) { return task(i); }, 1); })
module.exports = function(source) { var self = this; this.cacheable && this.cacheable(); var done = this.async(); var options = cloneDeep(loaderUtils.getOptions(this) || {}); options.dest = options.dest || ''; options.filename = options.filename || this.resourcePath; options.Evaluator = CachedPathEvaluator; var configKey, stylusOptions; if (this.stylus) { configKey = options.config || 'default'; stylusOptions = this.stylus[configKey] || {}; } else { configKey = options.config || 'stylus'; stylusOptions = this.options[configKey] || {}; } // Instead of assigning to options, we run them manually later so their side effects apply earlier for // resolving paths. var use = options.use || stylusOptions.use || []; options.import = options.import || stylusOptions.import || []; options.include = options.include || stylusOptions.include || []; options.set = options.set || stylusOptions.set || {}; options.define = options.define || stylusOptions.define || {}; options.paths = options.paths || stylusOptions.paths; if (options.sourceMap != null) { options.sourcemap = options.sourceMap; delete options.sourceMap; } else if (this.sourceMap) { options.sourcemap = { comment: false }; } var styl = stylus(source, options); var paths = [path.dirname(options.filename)]; function needsArray(value) { return (Array.isArray(value)) ? value : [value]; } if (options.paths && !Array.isArray(options.paths)) { paths = paths.concat(options.paths); options.paths = [options.paths]; } var manualImports = []; Object.keys(options).forEach(function(key) { var value = options[key]; if (key === 'use') { needsArray(value).forEach(function(plugin) { if (typeof plugin === 'function') { styl.use(plugin); } else { throw new Error('Plugin should be a function'); } }); } else if (key === 'set') { for (var name in value) { styl.set(name, value[name]); } } else if (key === 'define') { for (var defineName in value) { styl.define(defineName, value[defineName]); } } else if (key === 'include') { needsArray(value).forEach(styl.include.bind(styl)); } else if (key === 'import') { needsArray(value).forEach(function(stylusModule) { manualImports.push(stylusModule); }); } else { styl.set(key, value); if (key === 'resolve url' && value) { styl.define('url', resolver()); } } }); var shouldCacheImports = stylusOptions.importsCache !== false; var importsCache; if (stylusOptions.importsCache !== false) { if (typeof stylusOptions.importsCache === 'object') { importsCache = stylusOptions.importsCache; } else { if(!globalImportsCaches[configKey]) globalImportsCaches[configKey] = {}; importsCache = globalImportsCaches[configKey]; } } // Use input file system's readFile if available. The normal webpack input // file system is cached with entries purged when they are detected to be // changed on disk by the watcher. var readFile; try { var inputFileSystem = this._compiler.inputFileSystem; readFile = inputFileSystem.readFile.bind(inputFileSystem); } catch (error) { readFile = fs.readFile; } var boundResolvers = PathCache.resolvers(options, this.resolve); var pathCacheHelpers = { resolvers: boundResolvers, readFile: readFile, }; // Use plugins here so that resolve related side effects can be used while we resolve imports. (Array.isArray(use) ? use : [use]).forEach(styl.use, styl); when // Resolve manual imports like @import files. .reduce(manualImports, function resolveManualImports(carry, filename) { return PathCache.resolvers .reduce(boundResolvers, path.dirname(options.filename), filename) .then(function(paths) { return carry.concat(paths); }); }, []) // Resolve dependencies of .then(function(paths) { paths.forEach(styl.import.bind(styl)); paths.forEach(self.addDependency); var readFile = whenNodefn.lift(pathCacheHelpers.readFile); return when.reduce(paths, function(cache, filepath) { return readFile(filepath) .then(function(source) { return PathCache.createFromFile( pathCacheHelpers, cache, source.toString(), filepath ); }); }, { contexts: {}, sources: {}, imports: importsCache, }); }) .then(function(cache) { return PathCache .createFromFile(pathCacheHelpers, cache, source, options.filename); }) .then(function(importPathCache) { // CachedPathEvaluator will use this PathCache to find its dependencies. options.cache = importPathCache; importPathCache.allDeps().forEach(function(f) { self.addDependency(path.normalize(f)); }); // var paths = importPathCache.origins; styl.render(function(err, css) { if (err) { done(err); } else { if (styl.sourcemap) { styl.sourcemap.sourcesContent = styl.sourcemap.sources.map(function (file) { return importPathCache.sources[path.resolve(file)] }); } done(null, css, styl.sourcemap); } }); }) .catch(done); };
function reduceResolvers(resolvers, context, path) { return when .reduce(resolvers, function(result, resolver) { return result ? result : resolver(context, path); }, undefined); }
getTags(function (tags) { var logPath = path.join(__dirname, 'CHANGELOG.md'), log = fs.createWriteStream(logPath), commitCache = {}; function processTag(tag, callback) { var buffer = '', peek = tag[1]; tag = tag[0]; getLog(tag.tag, peek.tag, function (commits) { // Use the comparison with HEAD to remove commits which // haven't been included in a build/release yet. if (tag.tag === 'HEAD') { commits.forEach(function (commit) { commitCache[commit.hash] = true; }); return callback(''); } buffer += '## Release ' + tag.tag + '\n'; commits = commits .filter(function (commit) { // Get rid of jenkins' release tagging commits // Remove commits we've already spat out return ( commit.author !== 'TryGhost-Jenkins' && !commitCache[commit.hash] ); }) .map(function (commit) { buffer += '\n* ' + commit.message + ' (_' + commit.author + '_)'; commitCache[commit.hash] = true; }); if (!commits.length) { buffer += '\nNo changes were made in this build.\n'; } callback(buffer + '\n'); }); } // Get two weeks' worth of tags tags.unshift({'tag': 'HEAD'}); tags = tags .slice(0, 14) .map(function (tag, index) { return [ tag, tags[index + 1] || tags[index] ]; }); log.write('# Ghost Changelog\n\n'); log.write('_Showing ' + tags.length + ' releases._\n'); when.reduce(tags, function (prev, tag, idx) { /*jshint unused:false*/ return when.promise(function (resolve) { processTag(tag, function (releaseData) { resolve(prev + '\n' + releaseData); }); }); }, '') .then(function (reducedChangelog) { log.write(reducedChangelog); log.close(); done(true); }); });
function calculateReach(retweets) { debug('calculate', retweets); return when.reduce(retweets, function (a,b) {return a + b;}); }