Утро ВсеИспользование обещаний Nodejs (Bluebird) при загрузке и настройке модуля
Я прочесывал S.O. за последние пару дней, пытаясь найти ответ, который я понял/применил к моей ситуации, и теперь допустил поражение, в первую очередь из-за моего отсутствия понимания вокруг Promises (prom-n00b). Поэтому я в основном высказываю просьбу о помощи в моем примере, опубликованном ниже. Я думаю, что это довольно поясняющий, что я делаю, но в случае, если это не так, я пытаюсь:
- Нанесите синхронные конфигурации на сервер
- Грузоподьемности Logger модуль и экземпляр нового экземпляра из него как регистратор, а затем выполнить некоторые необходимые проверки (например, у нас есть файл журнала?) перед возвратом индикатора, чтобы сказать, что он загружен успешно (либо логический, либо сам журнал)
- Затем передайте этот регистратор на utils (они нуждаются в нем для регистрации)
- Наконец, вызовите обратный вызов, пройденный сценариями, запущенными
npm start
иnpm test
Очевидно, что в реальном мире происходит гораздо больше, но я пытался переделать код до того уровня, который я не получаю, а именно цепочки Promise.
Наконец, как долговременный пользователь обратных вызовов, которые никогда не пытались понять их (мозг должен работать по-другому, возможно), у любого из вас, чуваки, есть жемчужины мудрости, которые могут вызвать лампочку?
Большое спасибо заранее и да я знаю, что этот код, как он стоит не/не будет работать ;-)
код следующим образом:
server.js
var Promise = require('bluebird');
var fs = Promise.promisifyAll(require('fs-extra'));
var boss = {
start: function(callback) {
var p = new Promise.try(function() {
console.log('start');
})
.then(boss.applyConfig)
.then(boss.startLogger)
.then(function(lggr) {
console.log('logger setup complete: ' + lggr);
boss.logger = lggr;
return lggr;
})
.then(boss.loadUtils)
.finally(function() {
if (callback) callback();
})
.catch(function(err) {
console.log.call(null, '\033[31m' + err.stack + ' \033[39m');
});
},
applyConfig: function() {
console.log('applying config');
return 'config';
},
startLogger: function() {
console.log('starting logger');
var Logger = require('./Logger')(fs, Promise);
var logger = new Logger();
return new Promise(function(resolve, reject) {
var result = logger.init();
if (result) {
resolve(logger);
}
else {
reject(logger);
}
});
},
loadUtils: function(logger) {
console.log('loading utils with ' + logger);
boss.logger.log('loading utils with ' + logger);
return 'utils';
}
};
boss.start(function(){
console.log('done');
});
Logger.js
module.exports = function(fs, Promise) {
var Logger = function(options) {
this.filePath = (options && options.filePath) ? options.filePath : __dirname + '/../log/';
this.filename = (options && options.filename) ? options.filename : 'all.log';
};
Logger.prototype.init = function() {
var logger = this;
console.log('logger.init');
return new Promise(function(resolve) {
new Promise.resolve(logger.checkForLogFile()).then(function(exs) {
console.log('exs', exs);
return exs;
});
})
};
Logger.prototype.log = function(msg) {
// requires that the log file exists and that we have a stream to it (create stream function removed)
console.log.call(null, '\033[36mLogging: ' + msg + ' \033[39m');
};
Logger.prototype.checkForLogFile = function() {
var logger = this;
fs.existsAsync(logger.filePath + logger.filename).then(function (exists) {
console.log('exists', exists);
return exists;
});
};
return Logger;
};
Остерегаться для [отложенного анти-шаблона] (st ackoverflow.com/questions/23803743/what-is-the-deferred-antipattern-and-how-do-i-avoid-it) - вам не нужно «новое обещание» во всем - просто верните обещания и используйте 'then 'для цепочки. Более того - в 'checkForLogFile' вы не возвращаете обещание (вам не хватает' return' перед вашим 'fs.existsAsync' - хуже - 'existAsync' не работает с обещаниями, так как' exists' нарушен - если вы должны использовать его вместо 'statAsync' вместо этого, иначе избегайте его, так как он подвержен условиям гонки (файл создается между проверкой существования и следующая команда?) –
Также - верните 'p', а не принимайте обратный вызов в ваших обещанных методах (например,' start') –
Спасибо за хэдз-ап reAsAsync Benjamin - это многое объясняет! Просматривайте свои комментарии. –