Skip to content

Commit 47cb9c6

Browse files
authored
Implement emscripten_promise_race in promise.h (#19154)
This function propagates the result of its first input promise to settle, whether it is fulfilled or rejected.
1 parent 3c5bac9 commit 47cb9c6

File tree

5 files changed

+67
-1
lines changed

5 files changed

+67
-1
lines changed

src/library_promise.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,21 @@ mergeInto(LibraryManager.library, {
237237
});
238238
#if RUNTIME_DEBUG
239239
dbg('create: ' + id);
240+
#endif
241+
return id;
242+
},
243+
244+
emscripten_promise_race__deps: ['$promiseMap', '$idsToPromises'],
245+
emscripten_promise_race: function(idBuf, size) {
246+
var promises = idsToPromises(idBuf, size);
247+
#if RUNTIME_DEBUG
248+
dbg('emscripten_promise_race: ' + promises);
249+
#endif
250+
var id = promiseMap.allocate({
251+
promise: Promise.race(promises)
252+
});
253+
#if RUNTIME_DEBUG
254+
dbg('create: ' + id);
240255
#endif
241256
return id;
242257
}

src/library_sigs.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,7 @@ sigs = {
540540
emscripten_promise_any__sig: 'pppp',
541541
emscripten_promise_create__sig: 'p',
542542
emscripten_promise_destroy__sig: 'vp',
543+
emscripten_promise_race__sig: 'ppp',
543544
emscripten_promise_resolve__sig: 'vpip',
544545
emscripten_promise_then__sig: 'ppppp',
545546
emscripten_random__sig: 'f',

system/include/emscripten/promise.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,14 @@ __attribute__((warn_unused_result)) em_promise_t emscripten_promise_all_settled(
127127
__attribute__((warn_unused_result)) em_promise_t emscripten_promise_any(
128128
em_promise_t* promises, void** errors, size_t num_promises);
129129

130+
// Call Promise.race to create and return a new promise that settles once any of
131+
// the `num_promises` input promises passed in `promises` has been settled. If
132+
// the first input promise to settle is fulfilled, the resulting promise is
133+
// fulfilled with the same value. Otherwise, if the first input promise to
134+
// settle is rejected, the resulting promise is rejected with the same reason.
135+
__attribute__((warn_unused_result)) em_promise_t
136+
emscripten_promise_race(em_promise_t* promises, size_t num_promises);
137+
130138
#ifdef __cplusplus
131139
}
132140
#endif

test/core/test_promise.c

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,42 @@ static em_promise_result_t test_any(void** result, void* data, void* value) {
462462
return EM_PROMISE_MATCH_RELEASE;
463463
}
464464

465+
static em_promise_result_t test_race(void** result, void* data, void* value) {
466+
emscripten_console_log("test_race");
467+
assert(data == (void*)7);
468+
469+
em_promise_t in[2] = {emscripten_promise_create(),
470+
emscripten_promise_create()};
471+
em_promise_t fulfill = emscripten_promise_race(in, 2);
472+
em_promise_t fulfill_checked =
473+
emscripten_promise_then(fulfill, expect_success, fail, NULL);
474+
emscripten_promise_destroy(fulfill);
475+
emscripten_promise_resolve(in[1], EM_PROMISE_FULFILL, (void*)42);
476+
emscripten_promise_resolve(in[0], EM_PROMISE_REJECT, NULL);
477+
emscripten_promise_destroy(in[0]);
478+
emscripten_promise_destroy(in[1]);
479+
480+
in[0] = emscripten_promise_create();
481+
in[1] = emscripten_promise_create();
482+
em_promise_t reject = emscripten_promise_race(in, 2);
483+
em_promise_t reject_checked =
484+
emscripten_promise_then(reject, fail, expect_error, NULL);
485+
emscripten_promise_destroy(reject);
486+
emscripten_promise_resolve(in[0], EM_PROMISE_REJECT, (void*)42);
487+
emscripten_promise_resolve(in[1], EM_PROMISE_FULFILL, NULL);
488+
emscripten_promise_destroy(in[0]);
489+
emscripten_promise_destroy(in[1]);
490+
491+
em_promise_t to_finish[2] = {fulfill_checked, reject_checked};
492+
em_promise_t finish_test_race = emscripten_promise_all(to_finish, NULL, 0);
493+
494+
emscripten_promise_destroy(fulfill_checked);
495+
emscripten_promise_destroy(reject_checked);
496+
497+
*result = finish_test_race;
498+
return EM_PROMISE_MATCH_RELEASE;
499+
}
500+
465501
static em_promise_result_t finish(void** result, void* data, void* value) {
466502
emscripten_console_logf("finish");
467503

@@ -509,8 +545,10 @@ int main() {
509545
em_promise_t test5 =
510546
emscripten_promise_then(test4, test_all_settled, fail, (void*)5);
511547
em_promise_t test6 = emscripten_promise_then(test5, test_any, fail, (void*)6);
548+
em_promise_t test7 =
549+
emscripten_promise_then(test6, test_race, fail, (void*)7);
512550
em_promise_t assert_stack =
513-
emscripten_promise_then(test6, check_stack, fail, NULL);
551+
emscripten_promise_then(test7, check_stack, fail, NULL);
514552
em_promise_t end = emscripten_promise_then(assert_stack, finish, fail, NULL);
515553

516554
emscripten_promise_resolve(start, EM_PROMISE_FULFILL, NULL);
@@ -523,6 +561,7 @@ int main() {
523561
emscripten_promise_destroy(test4);
524562
emscripten_promise_destroy(test5);
525563
emscripten_promise_destroy(test6);
564+
emscripten_promise_destroy(test7);
526565
emscripten_promise_destroy(assert_stack);
527566
emscripten_promise_destroy(end);
528567

test/core/test_promise.out

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,7 @@ promise_any reasons:
2828
42
2929
43
3030
44
31+
test_race
32+
expected success: 42
33+
expected error: 42
3134
finish

0 commit comments

Comments
 (0)