JavaScript承诺依赖性处理

我有下面的代码示例。

var Promise = require('bluebird'); var model = function (object) { this.name = object.name; }; model.prototype.download = function () { var self = this; return new Promise(function (resolve, reject) { setTimeout(function () { resolve(); }, Math.random() * 100) }); }; model.prototype.process = function () { var self = this; return new Promise(function (resolve, reject) { setTimeout(function () { console.log('processed: ', self.name); resolve(); }, Math.random() * 100) }); }; var models = [new model({ name: 'user', requires: ['company'] }), new model({ name: 'address', requires: ['user', 'company'] }), new model({ name: 'company' })]; Promise.map(models, function (model) { return model.download() .then(function () { return model.process(); }); }); 

这个代码所需的输出是:

 processed: company // 1rst, because company model has no dependencies processed: user // 2nd, because user requires company processed: address // 3rd, because address requires company and user 

我需要以某种方式pipe理依赖关系。 只有当模型所需模型的所有process函数都已经被parsing时,才能触发model.process函数。

这只是一个小例子,我有很多具有多个依赖关系的模型。

我需要同步触发downloadfunction,尽快触发processfunction。 我不能等待所有的下载被解决,然后调用process

这是一个例子,你可以asynchronous遍历有向非循环图,而不需要多次评估单个节点。 请注意,依赖关系图中的循环会导致此实现中的死锁。

 function Model(name, requires) { this.name = name; this.requires = requires; }; // this function is available as `Promise.delay` when using bluebird function delay(x, v) { return new Promise(resolve => { setTimeout(() => { resolve(v); }, x); }); } Model.prototype.process = function () { console.log('started processing: ', this.name); return delay(Math.random() * 100 + 100).then(() => { console.log('finished processing: ', this.name); }); }; function Processor(models) { this.processMap = {}; this.models = models; models.forEach(m => { this.processMap[m.name] = { promise: null, model: m }; }); } Processor.prototype.processDependencies = function(model) { return Promise.all(model.requires.map(r => this.processByName(r))); }; Processor.prototype.process = function(model) { const process = this.processMap[model.name]; if (!process.promise) { process.promise = this.processDependencies(model) .then(() => model.process()); } return process.promise; }; Processor.prototype.processByName = function(modelName) { return this.process(this.processMap[modelName].model); }; function test() { const models = [ new Model('bottom', []), new Model('mid a', ['bottom']), new Model('mid b', ['bottom']), new Model('top', ['mid a', 'mid b']) ]; const processor = new Processor(models); Promise.all( models.map(m => processor.process(m)) ).then(allResults => { console.log("All process finished"); }, e => { console.error(e); }); } test(); 

asynchronous模块将完成这项工作: https : //github.com/caolan/async#control-flow

检查系列并行队列方法。