Hydra: Lightweight full-featured Promises, Async-Await Library in Swift

Overview

Async Functions for ECMAScript

The introduction of Promises and Generators in ECMAScript presents an opportunity to dramatically improve the language-level model for writing asynchronous code in ECMAScript. The spec text can be found here.

This proposal is implemented in a regenerator which can compile ES5 code containing async and await down to vanilla ES5 to run in existing browsers and runtimes.

This repo contains a complete example using a large number of the features of the proposal. To run this example:

npm install
regenerator -r server.asyncawait.js | node
Comments
  • How to cancel a running async function

    How to cancel a running async function

    Is it possible to short-circuit a running async function like one can do with a generator by calling its return method?

    A use case would be to have a finally block invoked in order to clean up resources, etc.

    question 
    opened by mnieper 83
  • Use execution context suspend/resume directly

    Use execution context suspend/resume directly

    This avoids using the generator machinery in favor of simply suspending and resuming execution contexts as appropriate. Fixes #49.


    Now most of the ceremony comes from PromiseCapability stuff. We could simplify it a bit if we did something like NewBuiltInPromise(), then use PromiseResolve and PromiseReject on it (which can never throw), instead of messing around with promise capabilities (which in theory can throw, although for %Promise% they cannot). PerformPromiseThen is also a bit awkward when you want to ignore the return value. But, not a big deal IMO.

    opened by domenic 33
  • Programmatically check if function is async

    Programmatically check if function is async

    Maybe this is part of the spec, but I was not able to find it in the text.

    Will it be possible to check if a function is an async function? This would be beneficial developing libraries around async functions. Just to make my point clear with pseudo code:

    async myFunc() {
    
    }
    
    myFync.isAsync // true
    
    opened by christianalfoni 32
  • Clarifying question: can await be used in top-level code?

    Clarifying question: can await be used in top-level code?

    In the proposal, it looks like "await" is to be used inside async functions.

    Can "await" be used in top-level code?

    The reason is, when teaching students, it makes a lot of sense to start with top-level code that does not contain function definitions, and it also makes sense to "await input", such as in this example using Iced CoffeeScript's "await". What would this example look like in this proposal?

    http://pencilcode.net/edit/guessmynumber

    question 
    opened by davidbau 31
  • Garbage Collection

    Garbage Collection

    Let's say I have an async function:

    async function foo() {
        try {
            var db = await getDatabase();
            await new Promise(() => {}); // db.doSomethingThatForgetsToResolve()
        } finally {
            if(db) db.close();
        }
    }
    

    And I call it:

    var g = f();
    
    • Does the finally block ever run?
    • Can garbage collection ever happen?
    opened by benjamingr 22
  • Proposal: Awaiting on Arguments

    Proposal: Awaiting on Arguments

    I was playing around with the current experimental implementation of async/await in Babel and thought it might be cool to be able to await on arguments. The most basic example:

    async function double(await num) {
      return num * 2;
    }
    

    This is the same as the following ES6:

    function double(num) {
      return num.then(x => x * 2);
    }
    

    Or the following ES5:

    function double(num) {
      return num.then(function (x) {
        return x * 2;
      });
    }
    

    As another example, consider awaiting on multiple arguments:

    async function multiply(await first, await second) {
      return first * second;
    }
    

    ~~As far as I'm aware, this is the best analog in the current proposal:~~

    Better analog (as pointed out in the comments):

    async function multiply(first, second) {
      [first, second] = [await first, await second];
      return first * second;
    }
    

    And as far as I'm aware, this is the best analog in ES6:

    function multiply(first, second) {
      return Promise.all([first, second]).then(([a, b]) => a * b);
    }
    

    Extending this even further, we can use the new ES6 arguments functionality with await:

    async function multiply(await {num: first}, await {num: second}) {
      return first * second;
    }
    

    Which is the same as:

    function multiply(first, second) {
      return Promise.all([first, second]).then(([{num: first}, {num: second}]) => first * second);
    }
    

    Additional example for awaiting on a property of an argument:

    async function double({await num}) {
      return num * 2;
    }
    

    Which is the same as:

    function double(obj) {
      return obj.then(({num}) => num * 2);
    }
    
    opened by knpwrs 22
  • Debugging async/await

    Debugging async/await

    I'm having spotty debugging experiences when I try to debug code with async/await using transform-async-to-generator babel plugin.

    @amcdnl had the same problems and opened an issue at https://github.com/mozilla/source-map/issues/221 which describes the issue in more detail and has some interesting discussion about debugging async/await.

    Is the debugging experience part of this proposal? Was this thought about before (e.g. in respect to how other languages having async/await syntax handle debugging)?

    opened by codepunkt 21
  • How to handle

    How to handle "unhandled Promise rejections"

    Promises can be "handled" after they are rejected. That is, one can call a promise's reject callback before providing a catch handler. This behavior is a little bothersome to me because one can write...

    var promise = new Promise(function(resolve) {
        kjjdjf(); // this function does not exist
    });
    

    ... and in this case, the Promise is rejected silently. If one forgets to add a catch handler, code will continue to silently run without errors. This could lead to lingering and hard-to-find bugs.

    In the case of Node.js, there is talk of handling these unhandled Promise rejections and reporting the problems. This brings me to ES7 async/await. Consider this example:

    async function getReadyForBed() {
      let teethPromise = brushTeeth();
      let tempPromise = getRoomTemperature();
    
      // Change clothes based on room temperature
      let temp = await tempPromise;
      // Assume `changeClothes` also returns a Promise
      if(temp > 20) {
        await changeClothes("warm");
      } else {
        await changeClothes("cold");
      }
    
      await teethPromise;
    }
    

    In the example above, suppose teethPromise was rejected (Error: out of toothpaste!) before getRoomTemperature was fulfilled. In this case, there would be an unhandled Promise rejection until await teethPromise.

    My point is this... if we consider unhandled Promise rejections to be a problem, Promises that are later handled by an await might get inadvertently reported as bugs. Then again, if we consider unhandled Promise rejections to not be problematic, legitimate bugs might not get reported.

    Thoughts on this?

    This is related to the discussion found in the Node.js project here: https://github.com/nodejs/node/issues/830

    opened by bminer 20
  • Proposal: Adapt return value to different Promise implementations

    Proposal: Adapt return value to different Promise implementations

    It would be a good thing if async functions would return the same type of promise that was awaited on in their function bodies. This would align with how typescript is implementing it (according to this issue). The async/await keywords could then be used together with various promise implementations without loosing the bells and whistles that comes with various Promise libraries such as bluebird, Q, WinJS and Dexie.

    External Promise implementations can have features that would be lost if converting them to the 'standard' Promise as suggested in the readme of this repository.

    Therefore, I would propose a more adaptive implemetation of spawn() that can accept and forward any A+ compatible Promise that was awaited for:

    function spawn(genF, self) {
        var gen = genF.call(self);
        function step(nextF,initial) {
            var next = nextF();
            if (next.done) {
                // finished with success, resolve the promise
                return initial ?
    
                    // Nothing was awaited. Direct return value must be converted
                    // to promise:
                    Promise.resolve(next.value) :
    
                    // Return the value as is and let the promise
                    // implementation take care of the A+ compatible promise chain
                    next.value;
            }
            // not finished, chain off the yielded promise and `step` again
            if (!next.value || typeof next.value.then !== 'function')
                return step(function(){
                    // Don't accept awaiting a non-promise such as "await 3;".
                    // By not accepting that, we could detect bugs better.
                    return gen.throw(new TypeError("Only acceptable to await a Thenable"));
                }, initial);
            return next.value.then(function (v) {
                return step(function () { return gen.next(v); });
            }, function (e) {
                return step(function () { return gen.throw(e); });
            });
        }
    
        try {
            return step(function() { return gen.next(undefined); }, true);
        } catch (e) {
            // Failure before code has yielded any Promise.
            return Promise.reject(e);
        }
    }
    

    Specifically, for my library, Dexie.js, there is a feature that enables 'Promise-Specific Data' which is analogue to 'thread static data' for promises. The entire Dexie API depends on that feature because it enables things like reentrant mutexes, implicit transaction scope, sub transaction awareness and some more API sugar. I believe that bluebird, Q, WinJS and others also would benefit from having this openess in how async/await behave.

    By not binding the async keyword to a specific implementation of Promise, we would allow new Promise implementations with features that we cannot think of today and still use them with async/await.

    opened by dfahlander 20
  • Awaiting within an arrow function

    Awaiting within an arrow function

    Assuming getJSON returns a promise for some JSON, does this work:

    async function renderChapters(urls) {
      urls.map(getJSON).forEach(j => addToPage((await j).html));
    }
    

    Does the await within the arrow function halt the execution of both the forEach and renderChapters, or does it error because the arrow function is not an async function?

    If not, should we have a way to await to the parent async function?

    opened by jakearchibald 20
  • Can you new an async function?

    Can you new an async function?

    It might be nice to allow new on an async function and have it do something useful...

    async function Person() {
      this.name = await getName();
    }
    
    // seems weird-ish.
    var p = new Person();
    p.then(person => console.log(person.name));
    
    
    // but seems better in another async function
    async function CreatePerson() {
      var person = await new Person();
      // ...
      return person;
    }
    
    // also allowing new argues for an additional async form:
    class Foo {
        async constructor() { ... }
    }
    

    The behavior of generators is to allow new (IOW, all other function forms can be newed) which argues for allowing it. However, generators don't allow this in their body. This would be a needless restriction for async functions so I'm not sure it applies.

    If anyone is aware of code today where new is expected to return a promise for an instance it would be a strong argument in favor of allowing new.

    I think the only viable alternative is to make newing an async function an error.

    question 
    opened by bterlson 19
Owner
Ecma TC39
Ecma International, Technical Committee 39 - ECMAScript
Ecma TC39
Lightweight async/await networking library with interceptor support - usable from iOS 13+.

Lightweight async/await networking library with interceptor support. ?? Getting started AsyncNetwork's session acts as a wrapper to URLSession by addi

Paul 9 Oct 4, 2022
A lightweight swift network layer with Combine, Async-Await, and a traditional completion block.

CombineNetwork A simple light-weight network library to make network requesting simpler. It supports newer techonology such as async/await as well as

Dushant Singh 4 Jan 3, 2022
⏳ Collection of Swift 5.5 async/await utility functions.

⏳ FunAsync Collection of Swift 5.5 async/await utility functions. Throw <-> Result conversion asyncThrowsToAsyncResult asyncResultToAsyncThrows More C

Yasuhiro Inami 23 Oct 14, 2022
🎭 Swift async/await & Actor-powered effectful state-management framework.

?? Actomaton ??‍?? Actor + ?? Automaton = ?? Actomaton Actomaton is Swift async/await & Actor-powered effectful state-management framework inspired by

Yasuhiro Inami 199 Dec 20, 2022
AsyncLocationKit - Async/await CoreLocation With Swift

AsyncLocationKit Wrapper for Apple CoreLocation framework with new Concurency Mo

AsyncSwift 89 Dec 30, 2022
Edit images and video with async / await in Swift, powered by Metal.

AsyncGraphics The core value type in AsyncGraphics is a Graphic. It's like an image, tho it can be used with various async methods. Documentation Swif

Anton Heestand 33 Dec 27, 2022
A Swift lib for network with async/await

SmileNetwork A Swift network utility with async/await applied UseAge enum MockEndpoint { case weather(cityId: String) } extension MockEndpoint: S

null 2 Jul 13, 2022
A simple network layer for use in small iOS projects with async/await support

SimpleNetwork Intro SimpleNetwork is simple network layer for use in small projects. Swift Package Manager Note: Instructions below are for using Swif

Alexandre Garrefa 1 Nov 30, 2021
Example project showing how to use async/await with iOS 13

ios13AsyncAwait Example project showing how to use async/await with iOS 13 Article This source code is a part of an article published at This Dev Brai

Michał Tynior 7 Oct 2, 2022
Using async / await on iOS 13: everything you need to know

Using async / await on iOS 13: everything you need to know! ?? Content This repository contains the code sample I've used during December 14th's lives

Vincent Pradeilles 11 Feb 1, 2022
iOS 13-compatible backports of commonly used async/await-based system APIs that are only available from iOS 15 by default.

AsyncCompatibilityKit Welcome to AsyncCompatibilityKit, a lightweight Swift package that adds iOS 13-compatible backports of commonly used async/await

John Sundell 367 Jan 5, 2023
straightforward networking and error handling with async-await and URLSession

AsyncAwaitNetworkingPlayground How To Run Just clone the project, open it and run. Some notes about AsyncAwaitNetworkingPlayground It's a straightforw

Fırat Yenidünya 17 Dec 11, 2022
AsyncTaskKit - contains some additions to async/await Task

AsyncTaskKit This repo contains some additions to async/await Task. In general i

Michał Zaborowski 0 Jan 2, 2022
Test app for the InStat company. The project uses MVVM architecture, interface created with SwiftUI, network requests with async/await

FootStats Test app for the InStat company. The Project uses MVVM architecture, interface created with SwiftUI, network requests with async/await using

Nizami Tagiyev 4 Dec 15, 2022
⚡️ Fast async task based Swift framework with focus on type safety, concurrency and multi threading

Our apps constantly do work. The faster you react to user input and produce an output, the more likely is that the user will continue to use your appl

Said Sikira 814 Oct 30, 2022
Async and concurrent versions of Swift’s forEach, map, flatMap, and compactMap APIs.

CollectionConcurrencyKit Welcome to CollectionConcurrencyKit, a lightweight Swift package that adds asynchronous and concurrent versions of the standa

John Sundell 684 Jan 9, 2023
Swift TableView pagination with async API request.

SwiftTableViewPagination Swift TableView pagination with async API request. Output UML Create puml file. $ cd SwiftTableViewPagination/scripts/swiftum

y-okudera 1 Dec 26, 2021
AsyncExtensions aims to mimic Swift Combine operators for async sequences.

AsyncExtensions AsyncExtensions provides a collection of operators, async sequences and async streams that mimics Combine behaviour. The purpose is to

AsyncCommunity 200 Dec 27, 2022
A demonstration for bridging between Combine and your new async functions

CombineAsyncually This is a DEMONSTRATION of how you can bridge the new async / await functionality in Swift 5.5 with Combine. There is NO WARRANTY. T

null 48 Dec 4, 2022