All Projects → vadymmarkov → When

vadymmarkov / When

Licence: other
⏰ A lightweight implementation of Promises in Swift

Programming Languages

swift
15916 projects

Labels

Projects that are alternatives of or similar to When

Imap Simple
Wrapper over node-imap, providing a simpler api for common use cases
Stars: ✭ 195 (-22%)
Mutual labels:  promise
Luch Request
luch-request 是一个基于Promise 开发的uni-app跨平台、项目级别的请求库,它有更小的体积,易用的api,方便简单的自定义能力。
Stars: ✭ 219 (-12.4%)
Mutual labels:  promise
Popsicle
Simple HTTP requests for node and the browser
Stars: ✭ 238 (-4.8%)
Mutual labels:  promise
Penpal
A promise-based library for securely communicating with iframes via postMessage.
Stars: ✭ 197 (-21.2%)
Mutual labels:  promise
Tickedoff
Tiny library (<200B gzip) for deferring something by a "tick"
Stars: ✭ 213 (-14.8%)
Mutual labels:  promise
Core Js
Standard Library
Stars: ✭ 15,854 (+6241.6%)
Mutual labels:  promise
Ppipe
pipes values through functions, an alternative to using the proposed pipe operator ( |> ) for ES
Stars: ✭ 192 (-23.2%)
Mutual labels:  promise
Task Easy
A simple, customizable, and lightweight priority queue for promises.
Stars: ✭ 244 (-2.4%)
Mutual labels:  promise
React Organism
Dead simple React state management to bring pure components alive
Stars: ✭ 219 (-12.4%)
Mutual labels:  promise
Api
Promise and RxJS APIs around Polkadot and any Substrate-based chain RPC calls. It is dynamically generated based on what the Substrate runtime provides in terms of metadata. Full documentation & examples available
Stars: ✭ 232 (-7.2%)
Mutual labels:  promise
Limitrr
Light NodeJS rate limiting and response delaying using Redis - including Express middleware.
Stars: ✭ 203 (-18.8%)
Mutual labels:  promise
Promisejs.org
a promise website to document and promote
Stars: ✭ 210 (-16%)
Mutual labels:  promise
Radwimps
君の then-then-then 世は Promise で Future
Stars: ✭ 229 (-8.4%)
Mutual labels:  promise
Amazon Mws
Amazon MWS NodeJS Wrapper
Stars: ✭ 196 (-21.6%)
Mutual labels:  promise
Await Of
await wrapper for easier errors handling without try-catch
Stars: ✭ 240 (-4%)
Mutual labels:  promise
Trilogy
TypeScript SQLite layer with support for both native C++ & pure JavaScript drivers.
Stars: ✭ 195 (-22%)
Mutual labels:  promise
Wx Promise Request
解决微信小程序 wx.request 请求的并发数限制、不支持异步问题
Stars: ✭ 226 (-9.6%)
Mutual labels:  promise
Escape From Callback Mountain
Example Project & Guide for mastering Promises in Node/JavaScript. Feat. proposed 'Functional River' pattern
Stars: ✭ 249 (-0.4%)
Mutual labels:  promise
Spirit
Modern modular library for building web applications
Stars: ✭ 241 (-3.6%)
Mutual labels:  promise
Massive Js
A data mapper for Node.js and PostgreSQL.
Stars: ✭ 2,521 (+908.4%)
Mutual labels:  promise

When

CI Status Version Carthage Compatible License Platform

Description

When is a lightweight implementation of Promises in Swift. It doesn't include any helper functions for iOS and OSX and it's intentional, to remove redundant complexity and give you more freedom and flexibility in your choices. It is type safe, thanks Swift generics, so you could create promises with whatever type you want.

When can easily be integrated into your projects and libraries to move your asynchronous code up to the next level.

Table of Contents

When Icon

Why?

To make asynchronous code more readable and standardized:

fetchJSON().then({ data: NSData -> [[String: AnyObject]] in
  // Convert to JSON
  return json
}).then({ json: [[String: AnyObject]] -> [Entity] in
  // Map JSON
  // Save to database
  return items
}).done({ items: [Entity] in
  self.items = items
  self.tableView.reloadData()
}).error({ error in
  print(error)
})

Usage

Promise

A promise represents the future value of a task. Promises start in a pending state and then could be resolved with a value or rejected with an error.

// Creates a new promise that could be resolved with a String value
let promise = Promise<String>()
// Resolves the promise
promise.resolve("String")
// Or rejects the promise
promise.reject(Error.notFound)
// Creates a new promise that is resolved with a String value
let promise = Promise({
  return "String"
})
// Creates a new promise that is rejected with an Error
let promise = Promise({
  //...
  throw Error.notFound
})

Callbacks of the current promise and all the chained promises (created with then) are executed on the main queue by default, but you can always specify the needed queue in init:

let promise = Promise<String>(queue: dispatch_get_main_queue())

Done

Adds a handler to be called when the promise object is resolved with a value:

// Create a new promise in a pending state
let promise = Promise<String>()
// Add done callback
promise.done({ value in
  print(value)
})
// Resolve the promise
promise.resolve("String")

Fail

Adds a handler to be called when the promise object is rejected with an Error:

// Create a new promise in a pending state
let promise = Promise<String>()
// Add fail callback
promise.fail({ error in
  print(error)
})
// Reject the promise
promise.reject(Error.notFound)

It's also possible to cancel a promise, which means it will be rejected with PromiseError.cancelled error. FailurePolicy can be used if you want to ignore this error in your fail handler:

// Create a new promise in a pending state
let promise = Promise<String>()
// This callback will not be called when a promise is cancelled
promise.fail({ error in
  print(error)
})
// This callback will be called when a promise is cancelled
promise.fail(policy: .allErrors, { error in
  print(error)
})
// Cancel the promise
promise.cancel()

Always

Adds a handler to be called when the promise object is either resolved or rejected. This callback will be called after done or fail handlers.

// Create a new promise in a pending state
let promise = Promise<String>()
// Add always callback
promise.always({ result in
  switch result {
  case let .success(value):
    print(value)
  case let .failure(error):
    print(error)
  }
})
// Resolve or reject the promise
promise.resolve("String") // promise.reject(Error.notFound)

Then

Returns a new promise that can use the result value of the current promise. It means that you could easily create chains of promises to simplify complex asynchronous operations into clear and simple to understand logic.

A new promise is resolved with the value returned from the provided closure:

let promise = Promise<NSData>()

promise
  .then({ data -> Int in
    return data.length
  }).then({ length -> Bool in
    return length > 5
  }).done({ value in
    print(value)
  })

promise.resolve("String".dataUsingEncoding(NSUTF8StringEncoding)!)

A new promise is resolved when the promise returned from the provided closure resolves:

struct Networking {
  static func GET(url: NSURL) -> Promise<NSData> {
    let promise = Promise<NSData>()
    //...
    return promise
  }
}

Networking.GET(url1)
  .then({ data -> Promise<NSData> in
    //...
    return Networking.GET(url2)
  }).then({ data -> Int in
    return data.length
  }).done({ value in
    print(value)
  })

then closure is executed on the main queue by default, but you can pass a needed queue as a parameter:

promise.then(on: dispatch_get_global_queue(QOS_CLASS_UTILITY, 0))({ data -> Int in
  //...
})

If you want to use background queue there are the helper methods for this case:

promise1.thenInBackground({ data -> Int in
  //...
})

promise2.thenInBackground({ data -> Promise<NSData> in
  //...
})

Recover

Returns a new promise that can be used to continue the chain when an error was thrown.

let promise = Promise<String>()
// Recover the chain
promise
  .recover({ error -> Promise<String> in
    return Promise({
      return "Recovered"
    })
  })
  .done({ string in
    print(string) // Recovered
  })
// Reject the promise
promise.reject(Error.notFound)

When

Provides a way to execute callback functions based on one or more promises. The when method returns a new "master" promise that tracks the aggregate state of all the passed promises. The method will resolve its "master" promise as soon as all the promises resolve, or reject the "master" promise as soon as one of the promises is rejected. If the "master" promise is resolved, the done callback is executed with resolved values for each of the promises:

let promise1 = Promise<Int>()
let promise2 = Promise<String>()
let promise3 = Promise<Int>()

when(promise1, promise2, promise3)
  .done({ value1, value2, value3 in
    print(value1)
    print(value2)
    print(value3)
  })

promise1.resolve(1)
promise2.resolve("String")
promise3.resolve(3)

Reactive extensions

Use the following extension in order to integrate When with RxSwift:

import RxSwift

extension Promise: ObservableConvertibleType {
  public func asObservable() -> Observable<T> {
    return Observable.create({ observer in
      self
        .done({ value in
          observer.onNext(value)
        })
        .fail({ error in
          observer.onError(error)
        })
        .always({ _ in
          observer.onCompleted()
        })

      return Disposables.create()
    })
  }
}

Installation

When is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'When'

For RxSwift extensions you can use CocoaPods subspecs:

pod 'When/RxSwift'

When is also available through Carthage. To install just write into your Cartfile:

github "vadymmarkov/When"

Author

Vadym Markov, [email protected]

Credits

Credits for inspiration go to PromiseKit and Then.

Contributing

Check the CONTRIBUTING file for more info.

License

When is available under the MIT license. See the LICENSE file for more info.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].