Skip to content

Commit 10f1902

Browse files
authored
implement promise start (#19)
1 parent 1897f04 commit 10f1902

File tree

4 files changed

+37
-0
lines changed

4 files changed

+37
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## Unreleased
44

5+
- Add `start` to the `promise` module.
56
- Add `wait` to `promise` module.
67

78
## v0.12.0 - 2024-08-19

src/gleam/javascript/promise.gleam

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ pub type Promise(value)
3131
@external(javascript, "../../gleam_javascript_ffi.mjs", "newPromise")
3232
pub fn new(a: fn(fn(value) -> Nil) -> Nil) -> Promise(value)
3333

34+
/// Create a new promise and resolve function. The first time the resolve function
35+
/// is called the promise resolves with that value.
36+
///
37+
/// This function is useful in cases where a reference to the promise and resolver
38+
/// are needed.
39+
///
40+
@external(javascript, "../../gleam_javascript_ffi.mjs", "start_promise")
41+
pub fn start() -> #(Promise(a), fn(a) -> Nil)
42+
3443
/// Create a promise that resolves immediately.
3544
///
3645
@external(javascript, "../../gleam_javascript_ffi.mjs", "resolve")

src/gleam_javascript_ffi.mjs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,14 @@ export function newPromise(executor) {
8989
);
9090
}
9191

92+
export function start_promise() {
93+
let resolve;
94+
const promise = new Promise((r) => {
95+
resolve = (value) => {r(PromiseLayer.wrap(value))}
96+
})
97+
return [promise, resolve]
98+
}
99+
92100
export function resolve(value) {
93101
return Promise.resolve(PromiseLayer.wrap(value));
94102
}

test/gleam/javascript/promise_test.gleam

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,25 @@ pub fn new_does_not_collapse_nested_promise_test() {
1919
})
2020
}
2121

22+
pub fn start_promise_test() {
23+
let #(p, resolve) = promise.start()
24+
promise.tap(p, fn(value) {
25+
let assert 1 = value
26+
})
27+
resolve(1)
28+
}
29+
30+
pub fn start_does_not_collapse_nested_promise_test() {
31+
let #(p, resolve) = promise.start()
32+
promise.tap(p, fn(value) {
33+
// If the `Promise(Promise(Int))` collapsed into `Promise(Int)` (as they
34+
// do for normal JS promises) then this would fail as the value would be the
35+
// int value `1`.
36+
let assert ObjectType = javascript.type_of(value)
37+
})
38+
resolve(promise.resolve(1))
39+
}
40+
2241
pub fn map_does_not_collapse_nested_promise_test() -> Promise(Promise(Int)) {
2342
promise.resolve(1)
2443
|> promise.map(promise.resolve)

0 commit comments

Comments
 (0)