December 26, 2012

False promises by promises

So the critiques to my previous article is that is too short or that the article "miss the point" without explicitly saying what is such "point". The best written arguments for promises I could find are this ones:
Now, in an asynchronous world, you can no longer return values: they simply aren't ready in time. Similarly, you can't throw exceptions, because nobody's there to catch them. So we descend into the so-called "callback hell," where composition of return values involves nested callbacks, and composition of errors involves passing them up the chain manually, and oh by the way you'd better never throw an exception or else you'll need to introduce something crazy like domains. The point of promises is to give us back functional composition and error bubbling in the async world. They do this by saying that your functions should return a promise, which can do one of two things: Become fulfilled by a value Become rejected with an exception
Let's go slowly through every bit.
(..)we descend into the so-called "callback hell," where composition of return values involves nested callbacks, and composition of errors involves passing them up the chain manually
This is dishonest; there are thousands of effective ways to avoid "callback hell" without introducing a library that changes the way Javascript is written and without pretending that every library should use that library:
function start(){
 
 start.time = new Date();
 fs.readFile("example.txt", readHandler );

}

function readHandler(err, data){

 if(err)throw err;
 console.log(data, start.time);
 
}
Oh by the way you'd better never throw an exception or else you'll need to introduce something crazy like domains.
This is a problem but not one that this library solves; you can't throw an exception in promises neither; you have to encapsulate it in a promise and becomes effective when it bubbles up to a callback that cares about such error.
The point of promises is to give us back functional composition and error bubbling in the async world.
The way you get effective error bubbling is not by introducing a new layer of complexity to the way Javascript is written, but to promote a sane consistent way of writing callbacks among Javascript developers preferably by using a simple popular solution like the one used in Node.js of returning the error in the first argument and data in the second (and optionally higher)
callback( error, data );
They do this by saying that your functions should return a promise, which can do one of two things:
Become fulfilled by a value
Become rejected with an exception
Exactly the same 2 things any well written callback should do:
Return a value
Or return an error.

2 comments:

  1. > This is dishonest; there are thousands of effective ways to avoid "callback hell" without introducing a library that changes the way Javascript is written and without pretending that every library should use that library:

    Of course there are ways to avoid it, and Promises is one of the best, it is a pattern pushed by big names (like jQuery or Microsoft as I mentioned in my previous comment). the code you put as an example only solves the nested callback hell, and it can be good enough for simple cases, but it you are constructing a bigger system, you'd better decouple the anync call from the response, Promises pattern does just that. You can return a promise object, and the code doesn't mind at all about who will listen to the response, because the client objects subscribe to the responses from the outside.

    > This is a problem but not one that this library solves; you can't throw an exception in promises neither; you have to encapsulate it in a promise and becomes effective when it bubbles up to a callback that cares about such error.

    I refer to the general pattern, not this particular library, and at least promises allows you to add a different callback for error conditions, which makes the code clearer, specially if your app is big.

    > The way you get effective error bubbling is not by introducing a new layer of complexity to the way Javascript is written, but to promote a sane consistent way of writing callbacks among Javascript developers preferably by using a simple popular solution like the one used in Node.js of returning the error in the first argument and data in the second (and optionally higher)

    Subscribing a callback to an error condition is a very popular solution too.


    ReplyDelete
  2. > You can return a promise object, and the code doesn't mind at all about who will listen to the response, because the client objects subscribe to the responses from the outside.

    This sounds good until you actually try to do it; for example in promises all the variables have to be passed around in the returned value or in variables saved in a shared scope. And Microsoft way to avoid this is to... create a callback hell: http://msdn.microsoft.com/en-us/library/windows/apps/jj676790.aspx?wa=wsignin1.0

    >and at least promises allows you to add a different callback for error conditions, which makes the code clearer, specially if your app is big.

    Many times you want to do something when there is an error using the same function; for example if we want to have a default value if the values that should be returned by an async function cannot be loaded:

    [CODE]// With promises
    fs.open("fs-promise.js", process.O_RDONLY).then(function(fd){
    return fs.read(fd, 4096)
    },function(error){
    return '\r\n';
    }).then(function(r){
    console.log(r);
    });

    // Withouth promises
    fs.open("fs-promise.js", process.O_RDONLY, function(fd, error){
    console.log( error ? "\r\n" : fs.read(fd, 4096) );
    });[/CODE]

    And this happens a lot and not only in small apps.

    ReplyDelete

You can use [CODE][/CODE] to post Javascript code.
You can start a sentence with ">" to make a quotation.