Skip to content

Commit 4717a3d

Browse files
feat: implement Then onFulfilled for Promise
1 parent a6213bb commit 4717a3d

File tree

4 files changed

+49
-0
lines changed

4 files changed

+49
-0
lines changed

napi-inl.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2813,6 +2813,28 @@ inline void Promise::CheckCast(napi_env env, napi_value value) {
28132813

28142814
inline Promise::Promise(napi_env env, napi_value value) : Object(env, value) {}
28152815

2816+
inline MaybeOrValue<Promise> Promise::Then(napi_value onFulfilled) const {
2817+
EscapableHandleScope scope(_env);
2818+
#ifdef NODE_ADDON_API_ENABLE_MAYBE
2819+
MaybeOrValue<Value> thenMethodMaybe = Get("then");
2820+
Function thenMethod = thenMethodMaybe.Unwrap().As<Function>();
2821+
#else
2822+
Function thenMethod = Get("then").As<Function>();
2823+
#endif
2824+
MaybeOrValue<Value> result = thenMethod.Call(*this, {onFulfilled});
2825+
#ifdef NODE_ADDON_API_ENABLE_MAYBE
2826+
if (result.IsJust()) {
2827+
return Just(scope.Escape(result.Unwrap()).As<Promise>());
2828+
}
2829+
return Nothing<Promise>();
2830+
#else
2831+
if (scope.Env().IsExceptionPending()) {
2832+
return Promise();
2833+
}
2834+
return scope.Escape(result).As<Promise>();
2835+
#endif
2836+
}
2837+
28162838
////////////////////////////////////////////////////////////////////////////////
28172839
// Buffer<T> class
28182840
////////////////////////////////////////////////////////////////////////////////

napi.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1574,7 +1574,10 @@ class Promise : public Object {
15741574

15751575
static void CheckCast(napi_env env, napi_value value);
15761576

1577+
Promise();
15771578
Promise(napi_env env, napi_value value);
1579+
1580+
MaybeOrValue<Promise> Then(napi_value onFulfilled) const;
15781581
};
15791582

15801583
template <typename T>

test/promise.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "napi.h"
2+
#include "test_helper.h"
23

34
using namespace Napi;
45

@@ -23,6 +24,22 @@ Value PromiseReturnsCorrectEnv(const CallbackInfo& info) {
2324
return Boolean::New(info.Env(), deferred.Env() == info.Env());
2425
}
2526

27+
Value ThenMethodOnFulfilled(const CallbackInfo& info) {
28+
auto deferred = Promise::Deferred::New(info.Env());
29+
Function onFulfilled = info[0].As<Function>();
30+
31+
Promise resultPromise = MaybeUnwrap(deferred.Promise().Then(onFulfilled));
32+
33+
bool isPromise = resultPromise.IsPromise();
34+
deferred.Resolve(Number::New(info.Env(), 42));
35+
36+
Object result = Object::New(info.Env());
37+
result["isPromise"] = Boolean::New(info.Env(), isPromise);
38+
result["promise"] = resultPromise;
39+
40+
return result;
41+
}
42+
2643
Object InitPromise(Env env) {
2744
Object exports = Object::New(env);
2845

@@ -31,6 +48,7 @@ Object InitPromise(Env env) {
3148
exports["rejectPromise"] = Function::New(env, RejectPromise);
3249
exports["promiseReturnsCorrectEnv"] =
3350
Function::New(env, PromiseReturnsCorrectEnv);
51+
exports["ThenMethodOnFulfilled"] = Function::New(env, ThenMethodOnFulfilled);
3452

3553
return exports;
3654
}

test/promise.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,10 @@ async function test (binding) {
1717
rejecting.then(common.mustNotCall()).catch(common.mustCall());
1818

1919
assert(binding.promise.promiseReturnsCorrectEnv());
20+
21+
const onFulfilled = (value) => value * 2;
22+
const result = binding.promise.thenMethodOnFulfilled(onFulfilled);
23+
assert.strictEqual(result.isPromise, true);
24+
const finalValue = await result.promise;
25+
assert.strictEqual(finalValue, 84);
2026
}

0 commit comments

Comments
 (0)