Real-Serious-Games / C-Sharp-Promise

Promises library for C# for management of asynchronous operations.
MIT License
1.19k stars 149 forks source link

Returning an "empty" promise? #28

Closed nah0y closed 7 years ago

nah0y commented 7 years ago

Hey guys! First of all, thanks a LOT for this super awesome library. Code is so much cleaner thanks to it!

Question: I have something like that:

Picture.Exists()
.Then(exists =>
{
    if (exists)
    {
        return Picture.Download();
    }
    else
    {
        // What should I do here to finish the promise and not go to the next "Then"?
    }
})
.Then(byteArray =>
{
    // Do something with the byte array
});

My question is in the comment of the code. If the file does not exists, I don't want to go to the next Then. And the compiler is asking me to return something but... what should I return?

Thanks a lot!

ashleydavis commented 7 years ago

In this case you should throw an exception. Consider creating a PictureNotFoundException.

Throwing an exception is the only way to terminate a chain of promises.

nah0y commented 7 years ago

Perfect thanks! How about returning a new Promise<byte[]> for example (and call .Resolve on it before returning it)?

zsoi commented 7 years ago

If "No picture" is a valid result that can be handled in your resolution chain, you could just return null as well (that'd be similar to JS behavior, where functions with no explicit return will return undefined).

Otherwise, I'd go with Ashleys approach and throw an exception and then handle the rejection accordingly, as that will have the result you want it to have (skip the resolution handlers until the next rejection handler). Also, for me, the code looks much cleaner as the "if-error-then" case is handled implicitely by the resolution chain and you don't need synchronous flow control to handle errors:

data = Fetch() if(data) { return data; } else { return replacementData; }

would convert to (assuming fetch() would reject the returned promise correctly)

return Fetch().Then(x => x).Catch(e => replacement);

nah0y commented 7 years ago

Thanks @zsoi ;)

ashleydavis commented 7 years ago

I should add it's perfectly ok to use some kind of 'empty' value. @zsoi has said null, but an empty byte array might also work:

Picture.Exists()
.Then(exists =>
{
    if (exists)
    {
        return Picture.Download();
    }
    else
    {
       return Promise.Resolved(new byte[0]);
    }
})
.Then(byteArray =>
{
    // Do something with the byte array
});