mirror of
https://github.com/simonbrunel/qtpromise.git
synced 2024-11-22 10:40:08 +08:00
Implement QPromise::timeout(msec, error)
This commit is contained in:
parent
b47ca0569e
commit
18324d3f44
@ -46,6 +46,9 @@ public:
|
|||||||
template <typename THandler>
|
template <typename THandler>
|
||||||
inline QPromise<T> tap(THandler handler) const;
|
inline QPromise<T> tap(THandler handler) const;
|
||||||
|
|
||||||
|
template <typename E = QPromiseTimeoutException>
|
||||||
|
inline QPromise<T> timeout(int msec, E&& error = E()) const;
|
||||||
|
|
||||||
inline QPromise<T> delay(int msec) const;
|
inline QPromise<T> delay(int msec) const;
|
||||||
inline QPromise<T> wait() const;
|
inline QPromise<T> wait() const;
|
||||||
|
|
||||||
|
@ -150,6 +150,26 @@ inline QPromise<T> QPromiseBase<T>::tap(THandler handler) const
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
template <typename E>
|
||||||
|
inline QPromise<T> QPromiseBase<T>::timeout(int msec, E&& error) const
|
||||||
|
{
|
||||||
|
QPromise<T> p = *this;
|
||||||
|
return QPromise<T>([&](
|
||||||
|
const QPromiseResolve<T>& resolve,
|
||||||
|
const QPromiseReject<T>& reject) {
|
||||||
|
|
||||||
|
QTimer::singleShot(msec, [=]() {
|
||||||
|
// we don't need to verify the current promise state, reject()
|
||||||
|
// takes care of checking if the promise is already resolved,
|
||||||
|
// and thus will ignore this rejection.
|
||||||
|
reject(std::move(error));
|
||||||
|
});
|
||||||
|
|
||||||
|
QtPromisePrivate::PromiseFulfill<QPromise<T> >::call(p, resolve, reject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline QPromise<T> QPromiseBase<T>::delay(int msec) const
|
inline QPromise<T> QPromiseBase<T>::delay(int msec) const
|
||||||
{
|
{
|
||||||
|
@ -4,6 +4,9 @@
|
|||||||
// QtPromise
|
// QtPromise
|
||||||
#include "qpromiseglobal.h"
|
#include "qpromiseglobal.h"
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QException>
|
||||||
|
|
||||||
namespace QtPromise {
|
namespace QtPromise {
|
||||||
|
|
||||||
class QPromiseError
|
class QPromiseError
|
||||||
@ -53,6 +56,16 @@ private:
|
|||||||
std::exception_ptr m_exception;
|
std::exception_ptr m_exception;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class QPromiseTimeoutException : public QException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void raise() const Q_DECL_OVERRIDE { throw *this; }
|
||||||
|
QPromiseTimeoutException* clone() const Q_DECL_OVERRIDE
|
||||||
|
{
|
||||||
|
return new QPromiseTimeoutException(*this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace QtPromise
|
} // namespace QtPromise
|
||||||
|
|
||||||
#endif // QTPROMISE_QPROMISEERROR_H
|
#endif // QTPROMISE_QPROMISEERROR_H
|
||||||
|
@ -49,6 +49,10 @@ private Q_SLOTS:
|
|||||||
void tapDelayedResolved();
|
void tapDelayedResolved();
|
||||||
void tapDelayedRejected();
|
void tapDelayedRejected();
|
||||||
|
|
||||||
|
void timeoutFulfilled();
|
||||||
|
void timeoutRejected();
|
||||||
|
void timeoutReject();
|
||||||
|
|
||||||
void delayFulfilled();
|
void delayFulfilled();
|
||||||
void delayRejected();
|
void delayRejected();
|
||||||
|
|
||||||
@ -659,6 +663,75 @@ void tst_qpromise::tapDelayedRejected()
|
|||||||
QCOMPARE(values, QVector<int>({2, 3}));
|
QCOMPARE(values, QVector<int>({2, 3}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_qpromise::timeoutFulfilled()
|
||||||
|
{
|
||||||
|
QElapsedTimer timer;
|
||||||
|
qint64 elapsed = -1;
|
||||||
|
|
||||||
|
timer.start();
|
||||||
|
|
||||||
|
auto p = QPromise<int>([](const QPromiseResolve<int>& resolve) {
|
||||||
|
QTimer::singleShot(1000, [=]() {
|
||||||
|
resolve(42);
|
||||||
|
});
|
||||||
|
}).timeout(2000).finally([&]() {
|
||||||
|
elapsed = timer.elapsed();
|
||||||
|
});
|
||||||
|
|
||||||
|
QCOMPARE(waitForValue(p, -1), 42);
|
||||||
|
QCOMPARE(p.isFulfilled(), true);
|
||||||
|
QVERIFY(elapsed < 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_qpromise::timeoutRejected()
|
||||||
|
{
|
||||||
|
QElapsedTimer timer;
|
||||||
|
qint64 elapsed = -1;
|
||||||
|
|
||||||
|
timer.start();
|
||||||
|
|
||||||
|
auto p = QPromise<int>([](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
|
||||||
|
QTimer::singleShot(1000, [=]() {
|
||||||
|
reject(QString("foo"));
|
||||||
|
});
|
||||||
|
}).timeout(2000).finally([&]() {
|
||||||
|
elapsed = timer.elapsed();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
QCOMPARE(waitForError(p, QString()), QString("foo"));
|
||||||
|
QCOMPARE(p.isRejected(), true);
|
||||||
|
QVERIFY(elapsed < 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_qpromise::timeoutReject()
|
||||||
|
{
|
||||||
|
QElapsedTimer timer;
|
||||||
|
qint64 elapsed = -1;
|
||||||
|
bool failed = false;
|
||||||
|
|
||||||
|
timer.start();
|
||||||
|
|
||||||
|
auto p = QPromise<int>([](const QPromiseResolve<int>& resolve) {
|
||||||
|
QTimer::singleShot(4000, [=]() {
|
||||||
|
resolve(42);
|
||||||
|
});
|
||||||
|
}).timeout(2000).finally([&]() {
|
||||||
|
elapsed = timer.elapsed();
|
||||||
|
});
|
||||||
|
|
||||||
|
p.fail([&](const QPromiseTimeoutException&) {
|
||||||
|
failed = true;
|
||||||
|
return -1;
|
||||||
|
}).wait();
|
||||||
|
|
||||||
|
QCOMPARE(waitForValue(p, -1), -1);
|
||||||
|
QCOMPARE(p.isRejected(), true);
|
||||||
|
QCOMPARE(failed, true);
|
||||||
|
QVERIFY(elapsed >= 2000 * 0.95); // Qt::CoarseTimer (default) Coarse timers try to
|
||||||
|
QVERIFY(elapsed <= 2000 * 1.05); // keep accuracy within 5% of the desired interval.
|
||||||
|
}
|
||||||
|
|
||||||
void tst_qpromise::delayFulfilled()
|
void tst_qpromise::delayFulfilled()
|
||||||
{
|
{
|
||||||
QElapsedTimer timer;
|
QElapsedTimer timer;
|
||||||
|
Loading…
Reference in New Issue
Block a user