/petkaantonov/bluebird
entity.create()
.then(function(udo) {
// once for either outcome
})
.catch(function(error) {
// once for either outcome
});
entity.create()
.then(function(udo) {
// any error that happens in here
// will get caught in ".catch()"
throw new Error('ops');
})
.catch(function(error) {});
entity.create()
.then(entity.read)
.then(entity.parseForApi)
.then(entity.process)
.catch(entity.onError);
var Promise = require('bluebird');
/* ... */
ClipEntity.prototype.fetchVideos = function() {
return new Promise(function(resolve, reject) {
fs.read(file, function(err, res) {
if (err) {
reject(err);
} else {
resolve(res);
}
});
});
};
var Promise = require('bluebird');
/* ... */
ClipEntity.prototype.showVideos = Promise.method(function() {
return this.fetchVideos();
});
return new Promise(function(resolve, reject) {
if (someCondition) {
var err = new Error('Not good');
reject(err);
}
});
ClipEntity.prototype.showVideos = Promise.method(function() {
if(someCondition) {
throw new Error('ops');
}
});
Foo.prototype.one = Promise.method(function() {
return this.two();
});
Foo.prototype.two = Promise.method(function() {
return 5;
});
/* ... */
foo.one()
.then(function(res) {
console.log(res); // 5
});
entity.create({name: 'thanasis'})
.then(function(udo) {
udo.name === 'thanasis'; // true
})
.catch(function(error) {
// deal with error.
});
ClipEntity.prototype._process = function(data) {
var clipProcessEnt = new ClipProcessEnt(data);
return clipProcessEnt.parseFiles()
.bind(clipProcessEnt)
.then(clipProcessEnt.isFileVideo)
.then(clipProcessEnt.storeClip)
.then(clipProcessEnt.storeThumb)
.then(clipProcessEnt.updateDatabase)
.then(clipProcessEnt.removeSourceFiles)
.catch(clipProcessEnt.rollback);
};
Create master methods
<--- Notice the .bind() !!
Process.prototype.rollback = Promise.method(function(err) {
log.finer('rollback() :: Removing Clip from DB, clipId:', this.clipId);
return this.clipEnt.delete(this.clipId)
.bind(this)
.catch(function (error) {
log.warn('rollback() :: NOT GOOD ERROR. File:', this.sourceFilePath,
' Failed to remove record for clip with ID:', this.clipId, 'Error:', error);
throw error;
})
.then(function() {
throw err;
});
});
The Rollback
<--- From clipEnt.delete()
<--- From Parent
ClipEntity.prototype._process = function(data) {
var clipProcessEnt = new ClipProcessEnt(data);
return clipProcessEnt.parseFiles()
.bind(clipProcessEnt)
.then(clipProcessEnt.isFileVideo)
.then(clipProcessEnt.storeClip)
.then(clipProcessEnt.storeThumb)
.then(clipProcessEnt.updateDatabase)
.then(clipProcessEnt.removeSourceFiles)
.return(data)
.catch(clipProcessEnt.rollback);
};
<-- Here it is!
ClipEntity.prototype._process = function(data) {
var clipProcessEnt = new ClipProcessEnt(data);
var promises = [];
promises.push(clipProcessEnt.isFileVideo());
promises.push(clipProcessEnt.storeClip());
promises.push(clipProcessEnt.storeThumb());
promises.push(clipProcessEnt.updateDatabase());
return Promise.all(promises)
.catch(clipProcessEnt.rollback);
};
ClipEntity.prototype._process = function(data) {
var clipProcessEnt = new ClipProcessEnt(data);
var promises = [];
promises.push(clipProcessEnt.isFileVideo());
promises.push(clipProcessEnt.storeClip());
promises.push(clipProcessEnt.storeThumb());
promises.push(clipProcessEnt.updateDatabase());
return Promise.all(promises, {concurrency: 10})
.catch(clipProcessEnt.rollback);
};
... with a throttle
// Compact
ClipExport.prototype._copyClips = Promise.method(function (filenames) {
return Promise.map(filenames, this._copyClip.bind(this));
});
// Expanded, better
ClipExport.prototype._copyClips = Promise.method(function (filenames) {
return Promise.resolve(filenames)
.map(this._copyClip);
// can chain easier now, error catch, etc
});
// Compact
ClipExport.prototype._copyClips = Promise.method(function (filenames) {
return Promise.map(filenames, this._copyClip.bind(this), {concurrency: 10});
});
// Expanded, better
ClipExport.prototype._copyClips = Promise.method(function (filenames) {
return Promise.resolve(filenames)
.map(this._copyClip, {concurrency: 10});
// can chain easier now, error catch, etc
});
... with a throttle
var Promise = require('bluebird');
// Promisify all methods of a module
var fs = Promise.promisifyAll(require('fs'));
fs.readFileAsync('one').then().catch();
// Promisify a single method
var readFileAsync = Promise.promisify(fs.readFile);
readFileAsync.then().catch();
Foo.prototype.one = Promise.method(function () {
return Promise.resolve([
'one',
'two'
])
map(function(val) {
return val + '-lol';
})
.spread(function(arg1, arg2) {
console.log(arg1, arg2);
// prints: "one-lol two-lol"
});
});
Foo.prototype.one = Promise.method(function (data) {
this.readAllFilesFor(data)
.bind(this)
.map(this.copyFile)
.then(function(filenames) {
return Promise.all([
this.process(filenames),
this.save(filenames),
this.notify(filenames),
]);
})
.spread(function(fromProcess, fromSave, fromNotify) {
return this.massup(fromProcess, fromSave, fromNotify)
})
.then(this.compress)
.then(this.sign)
.then(this.publish)
.catch(this.onError);
});
<-- filenames is the result of copyfiles()
<-- Parallel Async OPs
<-- spread() is one to one with the array
Thank you
(here is where you applaud)
Thanasis Polychronakis
@thanpolas
Questions
Thanasis Polychronakis
@thanpolas