Prechádzať zdrojové kódy

LibCore: Check if a promise is already resolved in Promise::map()

Karol Kosek 1 rok pred
rodič
commit
51fefb57fc

+ 34 - 0
Tests/LibCore/TestLibCorePromise.cpp

@@ -61,6 +61,40 @@ TEST_CASE(promise_chain_handlers)
     EXPECT(!rejected);
 }
 
+TEST_CASE(promise_map)
+{
+    Core::EventLoop loop;
+
+    auto promise = MUST(Core::Promise<int>::try_create());
+    auto mapped_promise = promise->map<int>([](int result) {
+        return result * 2;
+    });
+
+    loop.deferred_invoke([=] {
+        promise->resolve(21);
+    });
+
+    auto result = mapped_promise->await();
+    EXPECT(!result.is_error());
+    EXPECT_EQ(result.value(), 42);
+}
+
+TEST_CASE(promise_map_already_resolved)
+{
+    Core::EventLoop loop;
+
+    auto promise = MUST(Core::Promise<int>::try_create());
+    promise->resolve(21);
+
+    auto mapped_promise = promise->map<int>([](int result) {
+        return result * 2;
+    });
+
+    auto result = mapped_promise->await();
+    EXPECT(!result.is_error());
+    EXPECT_EQ(result.value(), 42);
+}
+
 TEST_CASE(threaded_promise_instantly_resolved)
 {
     Core::EventLoop loop;

+ 8 - 2
Userland/Libraries/LibCore/Promise.h

@@ -60,9 +60,15 @@ public:
 
     // Converts a Promise<A> to a Promise<B> using a function func: A -> B
     template<typename T>
-    RefPtr<Promise<T>> map(Function<T(Result&)> func)
+    NonnullRefPtr<Promise<T>> map(Function<T(Result&)> func)
     {
-        RefPtr<Promise<T>> new_promise = Promise<T>::construct();
+        NonnullRefPtr<Promise<T>> new_promise = Promise<T>::construct();
+
+        if (is_resolved())
+            new_promise->resolve(func(m_result_or_rejection->value()));
+        if (is_rejected())
+            new_promise->reject(m_result_or_rejection->release_error());
+
         on_resolution = [new_promise, func = move(func)](Result& result) -> ErrorOr<void> {
             new_promise->resolve(func(result));
             return {};