Skip to content

Commit 76e3d40

Browse files
committed
Introduce Async::Promise.fulfill.
1 parent 5331c2d commit 76e3d40

3 files changed

Lines changed: 72 additions & 0 deletions

File tree

lib/async/promise.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,5 +184,19 @@ def fulfill(&block)
184184
self.resolve(nil) unless @resolved
185185
end
186186
end
187+
188+
# If a promise is given, fulfill it with the result of the block.
189+
# If no promise is given, simply yield to the block.
190+
# This is useful for methods that may optionally take a promise to fulfill.
191+
# @parameter promise [Promise | Nil] The optional promise to fulfill.
192+
# @yields {...} The block to call to resolve the promise or return a value.
193+
# @returns [Object] The result of the block.
194+
def self.fulfill(promise, &block)
195+
if promise
196+
return promise.fulfill(&block)
197+
else
198+
return yield
199+
end
200+
end
187201
end
188202
end

releases.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Releases
22

3+
## Unreleased
4+
5+
- Introduce `Async::Promise.fulfill` for optional promise resolution.
6+
37
## v2.32.1
48

59
- Fix typo in documentation.

test/async/promise.rb

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,4 +648,58 @@
648648
expect(promise.wait).to be == :first
649649
end
650650
end
651+
652+
with ".fulfill" do
653+
it "fulfills the promise when given" do
654+
promise = Async::Promise.new
655+
656+
result = Async::Promise.fulfill(promise) do
657+
:block_result
658+
end
659+
660+
expect(result).to be == :block_result
661+
expect(promise.resolved?).to be == true
662+
expect(promise.wait).to be == :block_result
663+
end
664+
665+
it "simply yields when no promise is given" do
666+
result = Async::Promise.fulfill(nil) do
667+
:direct_result
668+
end
669+
670+
expect(result).to be == :direct_result
671+
end
672+
673+
it "handles exceptions when promise is given" do
674+
promise = Async::Promise.new
675+
test_error = StandardError.new("test error")
676+
677+
result = Async::Promise.fulfill(promise) do
678+
raise test_error
679+
end
680+
681+
expect(result).to be_nil
682+
expect(promise.failed?).to be == true
683+
expect(promise.value).to be == test_error
684+
end
685+
686+
it "propagates exceptions when no promise is given" do
687+
test_error = StandardError.new("test error")
688+
689+
expect do
690+
Async::Promise.fulfill(nil) do
691+
raise test_error
692+
end
693+
end.to raise_exception(StandardError, message: be =~ /test error/)
694+
end
695+
696+
it "works with falsy promise values" do
697+
# Test that it properly checks for nil/false, not just truthiness
698+
result = Async::Promise.fulfill(false) do
699+
:should_yield_directly
700+
end
701+
702+
expect(result).to be == :should_yield_directly
703+
end
704+
end
651705
end

0 commit comments

Comments
 (0)