/*:#localized(key: "AsynchronousOperations")
 # Asynchronous operations: when `main()` returns too soon

 Everything so far had one thing in common: the work finished *by the time `main()`
 returned*. That's the default deal with `Operation`: **the moment `main()` returns,
 the operation is considered finished.**

 Now picture uploading a job to a networked print server. You kick off the upload,
 and it completes *later*, in a callback. Watch what breaks:
 */
//#-editable-code
import Foundation
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

final class BrokenUploadOperation: Operation {
    override func main() {
        print("⬆️ Uploading... (plain Operation)")
        DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
            print("✅ Upload actually finished (but too late!)")
            PlaygroundPage.current.finishExecution()
        }
        // main() returns HERE, so the operation is "finished" right now,
        // a full second before the upload actually completes.
    }
}

let queue = OperationQueue()
let upload = BrokenUploadOperation()

upload.completionBlock = {
    print("🎉 completionBlock ran")
}

queue.addOperation(upload)
//#-end-editable-code
/*:#localized(key: "AsynchronousOperations-2")
 **Watch it run:** the order is `⬆️ Uploading...`, then `🎉 completionBlock ran`, then a
 full second later `✅ Upload actually finished`. The operation reported "done" while
 its real work was still in flight. Any operation that *depended* on this upload
 would start too early: the whole point of dependencies, defeated.

 [Previous](@previous)  |  page 4 of 7  |  [Next: Taking Over the State Machine](@next)
 */
