Skip to content

Commit 1c3839e

Browse files
committed
Add discard, always, and defer method
1 parent f87ff5e commit 1c3839e

File tree

2 files changed

+56
-14
lines changed

2 files changed

+56
-14
lines changed

Futures.xcodeproj/project.pbxproj

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,12 @@
129129
B757AE7120B8A5BA00850F92 /* Sources */ = {
130130
isa = PBXGroup;
131131
children = (
132-
B757AE7220B8A5BA00850F92 /* Future */,
132+
B757AE7220B8A5BA00850F92 /* Futures */,
133133
);
134134
path = Sources;
135135
sourceTree = "<group>";
136136
};
137-
B757AE7220B8A5BA00850F92 /* Future */ = {
137+
B757AE7220B8A5BA00850F92 /* Futures */ = {
138138
isa = PBXGroup;
139139
children = (
140140
B757AE7320B8A5BA00850F92 /* FutureResult.swift */,
@@ -144,15 +144,14 @@
144144
B79FF3B620BC6E34001A625C /* AnyFuture.swift */,
145145
B768073720C6C02E00402ECB /* FutureProvider.swift */,
146146
);
147-
name = Future;
148147
path = Futures;
149148
sourceTree = "<group>";
150149
};
151150
B757AE8220B8A5C700850F92 /* Framework */ = {
152151
isa = PBXGroup;
153152
children = (
154153
B757AE8320B8A5C700850F92 /* FutureTests */,
155-
B757AE8520B8A5C700850F92 /* Future */,
154+
B757AE8520B8A5C700850F92 /* Futures */,
156155
);
157156
path = Framework;
158157
sourceTree = "<group>";
@@ -166,30 +165,28 @@
166165
path = FuturesTests;
167166
sourceTree = "<group>";
168167
};
169-
B757AE8520B8A5C700850F92 /* Future */ = {
168+
B757AE8520B8A5C700850F92 /* Futures */ = {
170169
isa = PBXGroup;
171170
children = (
172171
B757AE8620B8A5C700850F92 /* Futures.h */,
173172
B757AE8720B8A5C700850F92 /* Info.plist */,
174173
);
175-
name = Future;
176174
path = Futures;
177175
sourceTree = "<group>";
178176
};
179177
B757AE8C20B8A60600850F92 /* Tests */ = {
180178
isa = PBXGroup;
181179
children = (
182-
B757AE8E20B8A60600850F92 /* FutureTests */,
180+
B757AE8E20B8A60600850F92 /* FuturesTests */,
183181
);
184182
path = Tests;
185183
sourceTree = "<group>";
186184
};
187-
B757AE8E20B8A60600850F92 /* FutureTests */ = {
185+
B757AE8E20B8A60600850F92 /* FuturesTests */ = {
188186
isa = PBXGroup;
189187
children = (
190188
B757AE8F20B8A60600850F92 /* FuturesTests.swift */,
191189
);
192-
name = FutureTests;
193190
path = FuturesTests;
194191
sourceTree = "<group>";
195192
};

Sources/Futures/Future.swift

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -466,15 +466,15 @@ public extension Future {
466466
/// Note that the provided callback is called regardless of whether this future is fulfilled or rejected.
467467
/// The returned `Future<T>` is fulfilled **only** if this and the provided future both are fullfilled.
468468
///
469-
/// In essence, the returned future will forward the result of this future, if the provided future
469+
/// In short, the returned future will forward the result of this future, if the provided future
470470
/// is fulfilled.
471471
///
472472
/// - Parameters:
473473
/// - queue: Dispatch queue to observe on.
474474
/// - initialResult: An initial result to begin the reduction.
475475
/// - callback: A callback that returns a `Future<Void>` to be deferred.
476476
/// - Returns: A future that will receive the eventual value.
477-
func `defer`(on queue: DispatchQueue = .futures, callback: @escaping () -> Future<Void>) -> Future<T> {
477+
func always(on queue: DispatchQueue = .futures, callback: @escaping () -> Future<Void>) -> Future<T> {
478478
let promise = Promise<T>()
479479

480480
whenResolved(on: queue) { result1 in
@@ -497,6 +497,29 @@ public extension Future {
497497
return promise.future
498498
}
499499

500+
/// Returns a new `Future<T>` that will resolve with the result of this `Future` **after** the provided callback
501+
/// runs.
502+
///
503+
/// Note that the provided callback is called regardless of whether this future is fulfilled or rejected.
504+
///
505+
/// This method is useful for times you want to execute code at the end of a chain of operations, regarless
506+
/// of whether successful or not.
507+
///
508+
/// - Parameters:
509+
/// - queue: Dispatch queue to observe on.
510+
/// - callback: Callback to run.
511+
/// - Returns: A future that will receive the eventual value.
512+
func `defer`(on queue: DispatchQueue = .futures, callback: @escaping () -> Void) -> Future<T> {
513+
let promise = Promise<T>()
514+
515+
whenResolved(on: queue) { result in
516+
callback()
517+
promise.resolve(result)
518+
}
519+
520+
return promise.future
521+
}
522+
500523
enum PollError: Error {
501524
case retryCountExceeded
502525
}
@@ -507,14 +530,14 @@ public extension Future {
507530
/// is acceptable.
508531
///
509532
/// - Parameters:
510-
/// - dispatchQueue: Dispatch queue to poll on,
533+
/// - queue: Dispatch queue to poll on,
511534
/// - future: Future used as the polling function.
512535
/// - interval: Time to wait between invoking subsequent futures.
513536
/// - retryCount: maxRetryCount Maximum number of times to invoke the supplied future
514537
/// - finished: Handler to invoke, resolving whether the result of the given promise is acceptable
515538
/// - Returns: A future that will receive the eventual value.
516539
static func poll<T>(
517-
on dispatchQueue: DispatchQueue = .futures,
540+
on queue: DispatchQueue = .futures,
518541
future: @escaping @autoclosure () -> Future<T>,
519542
interval: TimeInterval,
520543
maxRetryCount: Int,
@@ -534,7 +557,7 @@ public extension Future {
534557
if finished(value) {
535558
promise.fulfill(value)
536559
} else if numberOfRetries < maxRetryCount {
537-
dispatchQueue.asyncAfter(deadline: .now() + (numberOfRetries < 1 ? 0 : interval)) {
560+
queue.asyncAfter(deadline: .now() + (numberOfRetries < 1 ? 0 : interval)) {
538561
poll()
539562
}
540563
} else {
@@ -551,6 +574,28 @@ public extension Future {
551574

552575
return promise.future
553576
}
577+
578+
/// Returns a new Future<Void>, effectively discarding the result of the caller.
579+
///
580+
/// This method is useful when the value of a future is of no consequence.
581+
///
582+
/// - Parameter queue: Dispatch queue to discard on.
583+
/// - Returns: A future that will receive the eventual value.
584+
@discardableResult
585+
func discard(on queue: DispatchQueue = .futures) -> Future<Void> {
586+
587+
let promise = Promise<Void>()
588+
589+
whenFulfilled(on: queue) { _ in
590+
promise.fulfill()
591+
}
592+
593+
whenRejected { error in
594+
promise.reject(error)
595+
}
596+
597+
return promise.future
598+
}
554599
}
555600

556601
public extension Future {

0 commit comments

Comments
 (0)