tc39 / proposal-cancelable-promises

Former home of the now-withdrawn cancelable promises proposal for JavaScript
Other
375 stars 29 forks source link

try/catch/else/finally statements vs. Promise.prototype.then/else/catch/finally #48

Closed dnalborczyk closed 8 years ago

dnalborczyk commented 8 years ago

I was digging through the proposal, the presentation, the spec draft, and the github issues, and I'm trying to get my head around the following:

As of now it seems that else/catch statements are mutually exclusive. I was wondering if the Promise implementation will somehow 'mirror' the 'behavior' of the statements (to my understanding that's not the case).

It seems that 'else' is the new 'catch', so that probably applies to Promises as well, meaning ideally only one should be used, not both? Nonetheless, if one ends up using both, is the following below correct?

try/catch/else/finally statements

try {
    throw new Cancel();
} else (e) {
    // does not run
}
finally {
    // runs
}

try {
    throw new Error();
} else (e) {
    // runs, e instanceof Error
}
finally {
    // runs
}

// "legacy"
try {
    throw new Cancel();
} catch (e) {
    // runs
}
finally {
    // runs
}

// syntax not allowed
try {
    // ...
} else (e) {
    // ...
} catch (e) {
    // ...
}
finally {
    // ...
}

Promise.prototype.then/else/catch/finally (assuming finally does make it into the spec https://github.com/tc39/proposal-promise-finally)

chaining:

new Promise(() => { throw new Cancel() } )
    .then(() => {
        // does not run
    }, () => {
        // runs
    })
    .else(() => {
        // does not run, even if 'thenable rejection handler' was omitted
    })
    .catch(() => {
        // runs if 'thenable rejection handler' was omitted
    })
    .finally(() => {
        // runs
    })

new Promise(() => { throw new Error() } )
    .then(() => {
        // does not run
    }, () => {
        // runs
    })
    .else(() => {
        // runs if 'thenable rejection handler' was omitted
    })
    .catch(() => {
        // runs if 'thenable rejection handler' and
        // 'else handler' were omitted
    })
    .finally(() => {
        // runs
    })

branching:

const p = new Promise(() => { throw new Cancel() } )

p.then(() => {
    // does not run
}, () => {
    // runs
})

p.else(() => {
    // does not run
})

p.catch(() => {
    // runs
})

.finally(() => {
    // runs
});

const p = new Promise(() => { throw new Error() } )

p.then(() => {
    // does not run
}, () => {
    // runs
})

p.else(() => {
    // runs
})

p.catch(() => {
    // runs
})

p.finally(() => {
    // runs
})
domenic commented 8 years ago

Yes, that looks correct. You can also verify it by checking the spec.

dnalborczyk commented 8 years ago

Thx @domenic ! I'm quite a novice when it comes to spec reading ;)