This method returns a promise that will be fulfilled with the same value as the `input` promise and after at least `msec` milliseconds. If the `input` promise is rejected, the `output` promise is immediately rejected with the same reason.
This `handler` allows to observe the value of the `input` promise, without changing the propagated value. The `output` promise will be resolved with the same value as the `input` promise (the `handler` returned value will be ignored). However, if `handler` throws, `output` is rejected with the new exception. Unlike `finally`, this handler is not called for rejections.
Make sure that the chained value is not copied when `finally` is called for a fulfilled input promise. The value was copied 7 times in the previous version because it was captured in a lambda, which one copied multiple times.
Make QPromise thread safe but also ensure that continuation lambdas (then/fail/finally) are called in the thread of the promise instance they are attached to.
Make continuation methods const (then/fail/finally) and ensure that the resolved promise value/error is copied only when required, same for user lambdas (dispatching result is now fully handled by the PromiseData).
QFuture canceled with `QFuture::cancel()` now rejects attached promises with `QPromiseCanceledException`. In case the future is canceled because an exception (e) has been thrown, the promise is rejected with the same (e) exception (or `QUnhandledException` if not a subclass of `QException`).
Make sure that the promise state can only be changed by the promise producer (and not consumers) by removing the `fulfill` and `reject` methods from the instance members and introducing a new constructor accepting a resolver lambda. That also means that a promise can't anymore be default constructed.
Add the static `QPromise<T>::resolve` and `QPromise<T>::reject` methods to create synchronously fulfilled or rejected promises, and fix the `qPromise` helper to handle deduced promises (e.g. `qPromise(QFuture<int>()) -> QPromise<int>`).