Closed ghost closed 5 years ago
Hi @umbri, sorry, I don't completely understand. Do you propose to reject a promise with some predefined cancelled
error and provide a special catch
version to handle only those? In the example above a simple shared bool
flag seems sufficient...
@shoumikhin Hi, let me show a real world example: (simplified)
func testPromise() -> Promise<[Icon]> {
return Promise<[Icon]>(on: .global(qos: .userInitiated)) {
return self.loadHtml()
.then({ (html) -> Promise<[URL]> in
return self.parseHtml(with: html)
})
.then({ (urls) -> Promise<[Icon]> in
return Promises.any([
self.faviconByUrl(urls: urls),
Promises.all([
self.faviconSmall(),
self.faviconAppleTouch()
])
])
.then({ (result: [Maybe<[Icon]>]) -> Promise<[Icon]> in
fatalError() // do some transformations here ...
})
})
}
}
func loadHtml() -> Promise<String> {
fatalError()
}
func faviconAppleTouch() -> Promise<Icon> {
fatalError()
}
func faviconSmall() -> Promise<Icon> {
fatalError()
}
func faviconByUrl(urls: [URL]) -> Promise<[Icon]> {
return Promises.all(urls.map { self.download(url: $0) })
}
func parseHtml(with: String) -> Promise<[URL]> {
fatalError()
}
func download(url: URL) -> Promise<Icon> {
fatalError()
}
imagine you have something like this, and you don't know when user will cancel all this promise chain testPromise
, we need a simple method to do this
I see 2 approaches here:
download
will come in chunks, and promise is already started, we can get some chunks and the check if promise was rejected and reject downloadTask
func testIntegration2() { let token = CancellationToken()
self.testPromise(token: token)
.then { (icons) in
// on success
}
.catch { (error) in
// on fail or cancel
}
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
token.cancel() // simulate cancel
}
}
func testPromise(token: CancellationToken? = nil) -> Promise<[Icon]> {
return Promise<[Icon]>(on: .global(qos: .userInitiated)) {
return self.loadHtml(token: token)
.then({ (html) -> Promise<[URL]> in
return self.parseHtml(with: html)
})
.then({ (urls) -> Promise<[Icon]> in
return Promises.any([
self.faviconByUrl(urls: urls, token: token),
Promises.all([
self.faviconSmall(token: token),
self.faviconAppleTouch(token: token)
])
])
.then({ (result: [Maybe<[Icon]>]) -> Promise<[Icon]> in
fatalError() // do some transformations here ...
})
})
}
}
func loadHtml(token: CancellationToken? = nil) -> Promise<String> {
fatalError()
}
func faviconAppleTouch(token: CancellationToken? = nil) -> Promise<Icon> {
fatalError()
}
func faviconSmall(token: CancellationToken? = nil) -> Promise<Icon> {
fatalError()
}
func faviconByUrl(urls: [URL], token: CancellationToken? = nil) -> Promise<[Icon]> {
return Promises.all(urls.map { self.download(url: $0) })
}
func parseHtml(with: String) -> Promise<[URL]> {
fatalError()
}
func download(url: URL, token: CancellationToken? = nil) -> Promise<Icon> {
return Promise {
let request = URLRequest(url: url)
let task = URLSession(configuration: .ephemeral).dataTask(with: request) { data, response, error in
// fulfill or resolve
}
try token?.onCancel {
task.cancel()
}
task.resume()
}
}
Hi @umbri, did you see this example? Does it look like something you may find useful?
Hi @umbri, thank you for the discussion. Please reopen if you have any additional comments or questions.
current code:
proposal:
implement something like this: https://github.com/vadymmarkov/When#fail or maybe reevaluate #31 Here is a sketch: https://gist.github.com/umbri/7413f4c9b41cfc210561e01b6165a23e
Other suggestions ?