2016-06-27 3 views
1

У меня есть следующий пример кода.Обработка зависимостей JavaScript Promise

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 

мне нужно управлять каким-то зависимости. Функция model.process должна запускаться только тогда, когда все функции process требуемых моделей модели уже разрешены.

Это всего лишь небольшой пример, у меня много моделей с несколькими зависимостями.

Мне нужно активировать функции download синхронно и активировать функцию process как можно скорее. Я не могу дождаться, когда все загрузки будут решены, и позвоните по телефону process.

+0

Каковы Ваши проблемы? Вы хотите использовать обещание справиться с вышеуказанной ситуацией? И, пожалуйста, предоставьте дополнительную информацию о «Я не могу дождаться, когда все загрузки будут решены и вызовет процесс после». – Dnyanesh

+0

Ваш код ничего не показывает о «моделях модели, которые нужны модели». –

+0

Эй @ Днянеш, спасибо за ваш ответ, я обновил свой пример, чтобы сделать его более понятным. – Adam

ответ

2

Это пример того, как вы можете асинхронно перемещать ориентированный ациклический граф, не оценивая отдельные узлы несколько раз. Будьте осторожны, циклы в графике зависимостей вызывают взаимоблокировку в этой реализации.

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();

+0

FYI, ваша 'функция delay()' уже реализована как 'Promise.delay()' в bluebird. – Tomalak

+0

Спасибо, я упомянул об этом в коде –

+0

Отлично! Спасибо @TamasHegedus! – Adam

0

модуль асинхронной сделает работу: https://github.com/caolan/async#control-flow

Проверить на серии, параллельно и очередь методы.

+0

Спасибо, но как это справляется с зависимостями? – Adam

Смежные вопросы