1
1
/** A wrapper around [the JavaScript `Promise` class](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)
2
- that exposes its functions in a type-safe and Swifty way. The `JSPromise` API is generic over both
3
- `Success` and `Failure` types, which improves compatibility with other statically-typed APIs such
4
- as Combine. If you don't know the exact type of your `Success` value, you should use `JSValue`, e.g.
5
- `JSPromise<JSValue, JSError>`. In the rare case, where you can't guarantee that the error thrown
6
- is of actual JavaScript `Error` type, you should use `JSPromise<JSValue, JSValue>`.
2
+ that exposes its functions in a type-safe and Swifty way. The `JSPromise` API is generic over both
3
+ `Success` and `Failure` types, which improves compatibility with other statically-typed APIs such
4
+ as Combine. If you don't know the exact type of your `Success` value, you should use `JSValue`, e.g.
5
+ `JSPromise<JSValue, JSError>`. In the rare case, where you can't guarantee that the error thrown
6
+ is of actual JavaScript `Error` type, you should use `JSPromise<JSValue, JSValue>`.
7
7
8
- This doesn't 100% match the JavaScript API, as `then` overload with two callbacks is not available.
9
- It's impossible to unify success and failure types from both callbacks in a single returned promise
10
- without type erasure. You should chain `then` and `catch` in those cases to avoid type erasure.
11
- */
8
+ This doesn't 100% match the JavaScript API, as `then` overload with two callbacks is not available.
9
+ It's impossible to unify success and failure types from both callbacks in a single returned promise
10
+ without type erasure. You should chain `then` and `catch` in those cases to avoid type erasure.
11
+ */
12
12
public final class JSPromise : JSBridgedClass {
13
13
/// The underlying JavaScript `Promise` object.
14
14
public let jsObject : JSObject
@@ -18,35 +18,35 @@ public final class JSPromise: JSBridgedClass {
18
18
. object( jsObject)
19
19
}
20
20
21
- public static var constructor : JSFunction {
21
+ public static var constructor : JSFunction ? {
22
22
JSObject . global. Promise. function!
23
23
}
24
24
25
25
/// This private initializer assumes that the passed object is a JavaScript `Promise`
26
26
public init ( unsafelyWrapping object: JSObject ) {
27
- self . jsObject = object
27
+ jsObject = object
28
28
}
29
29
30
30
/** Creates a new `JSPromise` instance from a given JavaScript `Promise` object. If `jsObject`
31
- is not an instance of JavaScript `Promise`, this initializer will return `nil`.
32
- */
31
+ is not an instance of JavaScript `Promise`, this initializer will return `nil`.
32
+ */
33
33
public convenience init ? ( _ jsObject: JSObject ) {
34
34
self . init ( from: jsObject)
35
35
}
36
36
37
37
/** Creates a new `JSPromise` instance from a given JavaScript `Promise` object. If `value`
38
- is not an object and is not an instance of JavaScript `Promise`, this function will
39
- return `nil`.
40
- */
38
+ is not an object and is not an instance of JavaScript `Promise`, this function will
39
+ return `nil`.
40
+ */
41
41
public static func construct( from value: JSValue ) -> Self ? {
42
42
guard case let . object( jsObject) = value else { return nil }
43
- return Self . init ( jsObject)
43
+ return Self ( jsObject)
44
44
}
45
45
46
46
/** Creates a new `JSPromise` instance from a given `resolver` closure. `resolver` takes
47
- two closure that your code should call to either resolve or reject this `JSPromise` instance.
48
- */
49
- public convenience init ( resolver: @escaping ( @escaping ( Result < JSValue , JSValue > ) -> ( ) ) -> ( ) ) {
47
+ two closure that your code should call to either resolve or reject this `JSPromise` instance.
48
+ */
49
+ public convenience init ( resolver: @escaping ( @escaping ( Result < JSValue , JSValue > ) -> Void ) -> Void ) {
50
50
let closure = JSOneshotClosure { arguments in
51
51
// The arguments are always coming from the `Promise` constructor, so we should be
52
52
// safe to assume their type here
@@ -63,19 +63,19 @@ public final class JSPromise: JSBridgedClass {
63
63
}
64
64
return . undefined
65
65
}
66
- self . init ( unsafelyWrapping: Self . constructor. new ( closure) )
66
+ self . init ( unsafelyWrapping: Self . constructor! . new ( closure) )
67
67
}
68
68
69
69
public static func resolve( _ value: ConvertibleToJSValue ) -> JSPromise {
70
- self . init ( unsafelyWrapping: Self . constructor. resolve!( value) . object!)
70
+ self . init ( unsafelyWrapping: Self . constructor! . resolve!( value) . object!)
71
71
}
72
72
73
73
public static func reject( _ reason: ConvertibleToJSValue ) -> JSPromise {
74
- self . init ( unsafelyWrapping: Self . constructor. reject!( reason) . object!)
74
+ self . init ( unsafelyWrapping: Self . constructor! . reject!( reason) . object!)
75
75
}
76
76
77
77
/** Schedules the `success` closure to be invoked on sucessful completion of `self`.
78
- */
78
+ */
79
79
@discardableResult
80
80
public func then( success: @escaping ( JSValue ) -> ConvertibleToJSValue ) -> JSPromise {
81
81
let closure = JSOneshotClosure {
@@ -85,10 +85,11 @@ public final class JSPromise: JSBridgedClass {
85
85
}
86
86
87
87
/** Schedules the `success` closure to be invoked on sucessful completion of `self`.
88
- */
88
+ */
89
89
@discardableResult
90
90
public func then( success: @escaping ( JSValue ) -> ConvertibleToJSValue ,
91
- failure: @escaping ( JSValue ) -> ConvertibleToJSValue ) -> JSPromise {
91
+ failure: @escaping ( JSValue ) -> ConvertibleToJSValue ) -> JSPromise
92
+ {
92
93
let successClosure = JSOneshotClosure {
93
94
success ( $0 [ 0 ] ) . jsValue
94
95
}
@@ -99,7 +100,7 @@ public final class JSPromise: JSBridgedClass {
99
100
}
100
101
101
102
/** Schedules the `failure` closure to be invoked on rejected completion of `self`.
102
- */
103
+ */
103
104
@discardableResult
104
105
public func `catch`( failure: @escaping ( JSValue ) -> ConvertibleToJSValue ) -> JSPromise {
105
106
let closure = JSOneshotClosure {
@@ -108,11 +109,11 @@ public final class JSPromise: JSBridgedClass {
108
109
return . init( unsafelyWrapping: jsObject. catch!( closure) . object!)
109
110
}
110
111
111
- /** Schedules the `failure` closure to be invoked on either successful or rejected completion of
112
- `self`.
113
- */
112
+ /** Schedules the `failure` closure to be invoked on either successful or rejected completion of
113
+ `self`.
114
+ */
114
115
@discardableResult
115
- public func finally( successOrFailure: @escaping ( ) -> ( ) ) -> JSPromise {
116
+ public func finally( successOrFailure: @escaping ( ) -> Void ) -> JSPromise {
116
117
let closure = JSOneshotClosure { _ in
117
118
successOrFailure ( )
118
119
return . undefined
0 commit comments