@@ -10,6 +10,7 @@ namespace {
1010V8System v8System;
1111
1212int promiseTestResult = 0 ;
13+ int deferredPromiseTestResult = 0 ;
1314kj::String catchTestResult;
1415
1516struct PromiseContext : public jsg ::Object, public jsg::ContextGlobal {
@@ -98,6 +99,27 @@ struct PromiseContext: public jsg::Object, public jsg::ContextGlobal {
9899 return result;
99100 }
100101
102+ DeferredPromise<kj::String> makeDeferredPromise (jsg::Lock& js) {
103+ auto [p, r] = js.newDeferredPromiseAndResolver <int >();
104+ deferredResolver = kj::mv (r);
105+ return p.then (js, [](jsg::Lock&, int i) { return i * 2 ; })
106+ .then (js, [](jsg::Lock& js, int i) {
107+ return jsg::DeferredPromise<int >::resolved (i + 2 );
108+ }).then (js, [](jsg::Lock& js, int i) { return kj::str (i); });
109+ }
110+
111+ void deferredResolvePromise (Lock& js, int i) {
112+ KJ_ASSERT_NONNULL (deferredResolver).resolve (js, kj::mv (i));
113+ }
114+
115+ void setDeferredResult (jsg::Lock& js, DeferredPromise<kj::String> promise) {
116+ // Throwing away the result of `.then()` doesn't cancel it!
117+ promise
118+ .then (js, [](jsg::Lock&, kj::String str) {
119+ deferredPromiseTestResult = str.parseAs <int >();
120+ }).then (js, [](jsg::Lock&) { deferredPromiseTestResult += 60000 ; });
121+ }
122+
101123 JSG_RESOURCE_TYPE (PromiseContext) {
102124 JSG_READONLY_PROTOTYPE_PROPERTY (promise, makePromise);
103125 JSG_METHOD (resolvePromise);
@@ -111,9 +133,14 @@ struct PromiseContext: public jsg::Object, public jsg::ContextGlobal {
111133 JSG_METHOD (whenResolved);
112134
113135 JSG_METHOD (thenable);
136+
137+ JSG_READONLY_PROTOTYPE_PROPERTY (deferredPromise, makeDeferredPromise);
138+ JSG_METHOD (deferredResolvePromise);
139+ JSG_METHOD (setDeferredResult);
114140 }
115141
116142 kj::Maybe<Promise<int >::Resolver> resolver;
143+ kj::Maybe<DeferredPromise<int >::Resolver> deferredResolver;
117144};
118145JSG_DECLARE_ISOLATE_TYPE (PromiseIsolate, PromiseContext);
119146
@@ -192,5 +219,19 @@ KJ_TEST("thenable") {
192219 e.expectEval (" thenable({ then(res) { res(123) } })" , " number" , " 123" );
193220}
194221
222+ KJ_TEST (" jsg::DeferredPromise<T>" ) {
223+ Evaluator<PromiseContext, PromiseIsolate> e (v8System);
224+
225+ e.expectEval (" setDeferredResult(deferredPromise.then(i => i + 1 /* oops, i is a string */));\n "
226+ " deferredResolvePromise(123)" ,
227+ " undefined" , " undefined" );
228+
229+ KJ_EXPECT (deferredPromiseTestResult == 0 );
230+
231+ e.runMicrotasks ();
232+
233+ KJ_EXPECT (deferredPromiseTestResult == 62481 );
234+ }
235+
195236} // namespace
196237} // namespace workerd::jsg::test
0 commit comments