Skip to content

Commit 47b5694

Browse files
committed
Implement #zip for Promise
1 parent 2ad576d commit 47b5694

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

lib/concurrent/promise.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,22 @@ def flat_map(&block)
134134
child
135135
end
136136

137+
# Builds a promise that produces the result of self and others in an Array
138+
# and fails if any of them fails.
139+
#
140+
# @param [Array<Promise>] others
141+
#
142+
# @return [Promise]
143+
def zip(*others)
144+
others.reduce(self) do |p1, p2|
145+
p1.flat_map do |result1|
146+
p2.then do |result2|
147+
[result1, result2].flatten
148+
end
149+
end
150+
end
151+
end
152+
137153
protected
138154

139155
def set_pending

spec/concurrent/promise_spec.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,24 @@ module Concurrent
291291

292292
end
293293

294+
describe '#zip' do
295+
let(:promise1) { Promise.new(executor: executor) { 1 } }
296+
let(:promise2) { Promise.new(executor: executor) { 2 } }
297+
let(:promise3) { Promise.new(executor: executor) { 3 } }
298+
299+
it 'yields the results as an array' do
300+
composite = promise1.zip(promise2, promise3).execute
301+
sleep 0.1
302+
expect(composite.value).to eq([1,2,3])
303+
end
304+
305+
it 'fails if one component fails' do
306+
composite = promise1.zip(promise2, rejected_subject, promise3).execute
307+
sleep 0.1
308+
expect(composite).to be_rejected
309+
end
310+
end
311+
294312
context 'fulfillment' do
295313

296314
it 'passes the result of each block to all its children' do

0 commit comments

Comments
 (0)