Giter Site home page Giter Site logo

async's Introduction

Async Swift

THIS IS A TOY IMPLEMENTATION AND SHOULD NOT BE USED IN PRODUCTION

(This was originally writen for Swift 1.x; I have updated the code for Swift 5 compatibility, but it's still a toy.)

This framework implements C#-like async/await primitives in Swift. Owing to some problems with the current operating system bindings, together with the need for a tiny bit of assembly language to make this work, the guts of the implementation are currently written in C.

The implementation could be adapted to work with Objective-C or C++ in a relatively straightforward manner.

Usage

Basic usage is as follows:

let task = async { () -> Int in
  return 5
}

let result = await(task)

Note that the type of the block is not optional.

You can return any Swift object you like, and the result is returned from the await call.

Obviously, it's permissible to invoke asynchronous tasks within asynchronous tasks, for instance

let task = async { () -> Int in
  let subtask = async { () -> Int in
    return 15
  }

  return await(subtask) * 2
}

let result = await(task)

Neither of these examples are particularly useful, so let’s give an example that is:

let task = async { () -> () in
  let fetch = async { (t: Task<Data>) -> Data in
    var data : Data?
    let session = URLSession(configuration: .default)
    let task = session.dataTask(with: URL(string: "http://www.google.com")!) {
      (d: Data!, r: URLResponse!, error: Error!) -> Void in
      data = d
      Async.wake(t)
    }
	task.resume()
    Async.suspend()
    return data!
  }

  let data = await(fetch)
  let str = String(decoding: data, as: UTF8.self)

  print(str)
}

You need to do a little set-up to make this work in your Cocoa/Cocoa Touch code, namely at some point you need to bind the Async module to the run loop with

Async.schedule(runLoop: RunLoop.current)

After doing that, if you invoke the code above, you’ll find that it fetches the Google home page into a string, which is returned as the result of task.

Note: You must not call await directly from a non-async context in a Cocoa program unless you are certain the task in question has completed. Doing so will trigger an assertion failure.

await semantics

async and await do not behave the way you might naïvely assume. If you call await (or Async.suspend) in an async context, control will return to the calling frame. It does not block. All that is suspended is execution within the async context.

The only time that await will block is if you are at the top level, outside of any async context. In that case, it will block the top level (but will continue running any async code as it becomes ready) until the specified task is complete.

If you're using this module in a Cocoa or Cocoa Touch program, and you want to run asynchronous code on the main thread, you can tell the framework that you want it to attach to the run loop, as shown before, with

Async.schedule(runLoop: RunLoop.current)

This also works for CFRunLoopRef, and it will work with the main dispatch queue as well if your programs use those instead.

Once you have done that, async tasks that you start from event handlers (or from blocks dispatched by the main dispatch queue) will continue to run to completion automatically. The framework does this by scheduling callbacks for itself in the run loop at appropriate times.

Async.suspend() and Async.wake()

These two functions allow you to suspend the current async context, and to wake a previously suspended context, respectively. They are used to interface async code with code that uses other methods of asynchronous behaviour (e.g. threads, dispatch queues, callbacks, completion blocks and so on).

Waking is not instant; the context will resume from the point of the Async.suspend call when either (a) await is called at top level and has to wait, or (b) your program returns to the run loop or dispatch queue with which the Async module is scheduled.

Note that the order that suspended async contexts resume is not guaranteed.

Threading support

The Async module is designed to work with threads in the following manner; each thread has its own entirely separate pool of async contexts, and its own distinct set of async tasks. You must not attempt to await on a task that is owned by another thread.

Important: dispatch queues other than the main queue do not guarantee that tasks will be invoked on the same thread. This applies even to serial queues, and is the reason that you must only ever pass the main dispatch queue to the Async.schedule function.

It is safe to use async contexts within a block dispatched to a queue, but bear in mind that you cannot await on a task from a different block, though it is certainly permissible to call Async.wake on one.

async's People

Contributors

al45tair avatar

Watchers

 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.