Promises, the middle state : negociation
On Thu, May 15, 2014 at 11:33 AM, Michaël Rouges <michael.rouges at gmail.com> wrote:
Hi all,
As I totally agree that a promise can only be resolved or rejected once ... so I think his behavior is perhaps too black or white.
As IRL, when we receive a promise, we expect that the author makes every effort to resolve it, by any way.
Progammatically, we can wish the same.
By example, we can have :
an error to ignore an error that requires to execute other operations leading to
a rejection a continuation a retry
To cover all these cases, in the current promises state, we can have (a quite) complex promises, easily solvable.
My idea? the negociation, where the goal is to find a solution to resolve it (rejection reduction).
For the promise "fn" argument, to add an optional "negociate" argument.
promise = new Promise(function (resolve, reject, negociate) { // the promise body });
An the related Promise.negociate method like :
Promise.negociate = function negociate(resolve, reject, negociate, retry, value) { };
That returns a promise, negociable too, where :
resolve is shared with the original promise (that contains the negociate call) to continue the process reject is shared with the original promise (that contains the negociate call) negociate, it's own negociation, for multiple attempts/behaviors retry to recall the original promise fn argument (compliant with the promises concept, since our promise was neither rejected nor resolved, at this point) value (or values, I'm not sure) to pass some infos/tools that we need to take our decision, in the negociation process
Lemme your advices. ;)
This is just normal promise chaining. If you get a promise and want to make sure it resolves in a particular way, just use .then() or .catch() to create a new promise that handles things the way you want.
I don't pretend that impossible to do with current promises.
I'm just saying that we can get a complexity that could be easily avoided.
And a catch/then doesn't allow to return in the first promise onFulfilled, without embedded promises.
I think a practical example might better illustrate the thing.
Imagine, we have to check a data integrity, firstly internal, or from external sources, if the internal data is corrupted.
The integrity controller is a foreign promisable controller , with a custom hash method & a fingerprint... we can't touch it.
var foreignController;
foreignController = (function () {
var fingerPrint,
hash,
controller;
fingerPrint = 'aforeignfingerprint';
hash = function hash(data) {
// foreign ownmade hash calculator
};
controller = function controller(resolve, reject, negociate) {
var data,
isValid,
sources;
data = this.data;
isValid = fingerPrint === hash(data);
if (isValid) {
return resolve(data);
}
sources = this.sources;
if (sources.length) {
// not an error, we only remove that source
// and try with the next one
return negociate(sources.shift());
}
reject(new Error('No valid data found'));
};
return controller;
}());
Now, the data ownmade data checker :
var getDataSync,
onFulFilled,
onRejected,
onNegociated,
handler,
controller;
getDataSync function getDataSync(source) {
// data collector
};
onFulFilled = function onFulFilled(value) {
// valid data treatment
};
onRejected = function onRejected(reason) {
// no valid data found
};
onNegociated = function onNegociated(resolve, reject, negociate, retry,
value) {
var source;
source = this.sources[0];
this.data = getDataSync(source);
console.log('data source corrupted : ' + value);
retry();
};
handler = {
data: 'some data',
sources: ['internal', 'an.external.url', 'another.external.url', '...']
};
controller = foreignController.bind(handler);
new Promise(controller)
.then(onFulFilled, onRejected, onNegociated.bind(handler))
/* a lot of thens */;
Personnaly, I don't see how the current promises can solve it as simply.
Michaël Rouges - Lcfvs - @Lcfvs
var sources = [internal, external1, external2];
function doStuff (e) {
// likely check if it's the right kind of error;
var url = sources.shift();
if (typeof url === 'undefined) {
return Promise.reject(new Error('out of sources'));
}
return get(url).then(check).catch(doStuff);
}
As I totally agree that a promise can only be resolved or rejected once ... so I think his behavior is perhaps too black or white.
As IRL, when we receive a promise, we expect that the author makes every effort to resolve it, by any way.
Progammatically, we can wish the same.
By example, we can have :
To cover all these cases, in the current promises state, we can have (a quite) complex promises, easily solvable.
My idea? the negociation, where the goal is to find a solution to resolve it (rejection reduction).
For the promise "fn" argument, to add an optional "negociate" argument.
An the related Promise.negociate method like :
That returns a promise, negociable too, where :
Lemme your advices. ;)
Michaël Rouges - Lcfvs - @Lcfvs