Git Product home page Git Product logo

asyncawait's Introduction

AsyncAwait Maintenance Deprecated Open Source Love png1

master dev
Build Status Build Status

About

This is a simple async/await implementation for Swift. This concept might become part of Swift at some point. Async & Await was Introduced in Swift 5.5, so this library is no longer necessary.

Traditional callbacks are hell. Writing callbacks that pass control flow to a function is better, but obfuscates the control flow. Promises are a decent solution, but after writing my own Promise based on this, I felt its design to be somewhat fishy. Swift's type inference in Xcode also slows down in larger codebases, blocking flow and slowing compilation time.

In all honesty, Combine is likely the future of iOS, so go learn that. It's much better than RxSwift. However, there's something I conceptually prefer about async / await over reactive solutions. You write code like you read a book, which to me, seems more intuitive. Reactive programming is great in some cases, as it reduces state, but to me it's not to be used everywhere, as it often obfuscates easy things, and there's no shame in admitting that. Programming shouldn't be made harder than it already is, and we're all guilty of doing it.

Nonetheless, after much searching, I found this library. It contains a really great idea using DispatchQueue to mimic async and await. However the implementation is based around using Promises, which I didn't want to use. So I took the key idea and hacked something simple together.

Before using, it's worth reading this grounded article. It makes some great points about new abstractions often hiding fundamental problems in your code design / thinking. Remember callbacks aren't necessarily bad, but this solution definitely seems to improve many of the key problems faced using callbacks.

See this in a real ios project, or mac project.

Installation

Carthage compatible

// Cartfile
github "larromba/asyncawait" ~> 2.0
// Terminal
carthage update

Usage

// 
// comparing callback approaches
//

// 1. callback hell:

func foo(completion: (Result<String, Error>) -> Void) {
    someLongFunction { result in
        switch result {
        case .success(let value):
            //...
            self.someLongFunction2 { result in
                switch result {
                case .success(let value):
                    //...
                    completion(.success("bar"))
                case .failure(let error):
                    completion(.failure(error))
                }
            }
        case .failure(let error):
            completion(.failure(error))
        }
    }
}

// 2. passing the control flow around

func foo(completion: (Result<String, Error>) -> Void) {
    someLongFunction { result in
        switch result {
        case .success(let value):
            //...
            foo2(completion: completion)
        case .failure(let error):
            completion(.failure(error))
        }
    }
}

func foo2(completion: (Result<String, Error>) -> Void) {
    someLongFunction2 { result in
        switch result {
        case .success(let value):
            //...
            completion(.success("bar"))
        case .failure(let error):
            completion(.failure(error))
        }
    }
}

// 3. using promises

func foo() -> Single<String> {
    return Single.create { seal in
        let value = someLongFunction
            .flatMap(someLongFunction2)
            .flatMap(someLongFunction3)
        //...
        seal(.success("bar"))
        return Disposables.create()
    }
}

// 4. using await / async
// example #1

func foo() -> Async<String, Error> {
    return Async { completion in
        async({
            let value1 = try await(self.someLongFunction(...))
            let value2 = try await(self.someLongFunction2(...))
            //...
            completion(.success("bar"))
        }, onError: { error in
            completion(.failure(error))
        })
    }
}

// example #2

func foo() -> Async<String, Error> {
    return Async { completion in
        async({
            let allThoseOperations = (0..<100).map { _ in foo() }
            let results = try awaitAll(allThoseOperations)
            //...
            completion(.success("bar"))
        }, onError: { error in
            completion(.failure(error))
        })
    }
}

Licence

MIT license

asyncawait's People

Contributors

larromba avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.