Explorar el Código

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

Karol Kosek hace 1 año
padre
commit
51fefb57fc
Se han modificado 2 ficheros con 42 adiciones y 2 borrados
  1. 34 0
      Tests/LibCore/TestLibCorePromise.cpp
  2. 8 2
      Userland/Libraries/LibCore/Promise.h

+ 34 - 0
Tests/LibCore/TestLibCorePromise.cpp

@@ -61,6 +61,40 @@ TEST_CASE(promise_chain_handlers)
     EXPECT(!rejected);
     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)
 TEST_CASE(threaded_promise_instantly_resolved)
 {
 {
     Core::EventLoop loop;
     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
     // Converts a Promise<A> to a Promise<B> using a function func: A -> B
     template<typename T>
     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> {
         on_resolution = [new_promise, func = move(func)](Result& result) -> ErrorOr<void> {
             new_promise->resolve(func(result));
             new_promise->resolve(func(result));
             return {};
             return {};