Home

Awesome

promise-async

GitHub Test GitHub Lint

The goal of promise-async is to port Promise & Async from JavaScript to Lua.

A value returned by async function in JavaScript is actually a Promise Object. It's incomplete and inflexible for using an async function wrapped by bare coroutine without Promise in almost Lua implementation.

Features

Demonstration

https://user-images.githubusercontent.com/17562139/169118448-9468909b-dbde-4dde-9308-ffe71abb24cd.mp4

Script

demo.lua

https://github.com/kevinhwang91/promise-async/blob/3f6dcb2f0f546e8be7e170785f07f71ef6afab34/examples/demo.lua#L17-L82

demo.js

https://github.com/kevinhwang91/promise-async/blob/3f6dcb2f0f546e8be7e170785f07f71ef6afab34/examples/demo.js#L1-L58

Quickstart

Requirements

Luv is a default EventLoop for promise-async. It doesn't mean promise-async must require it. In fact, promise-async require a general EventLoop module which Luv like.

Installation

As a plugin for Neovim platform

Install with Packer.nvim:

use {'kevinhwang91/promise-async'}

or

use_rocks {'promise-async'}

As a library from Luarocks

  1. luarocks install promise-async
  2. luarocks install luv or implement an EventLoop interface to adapt your platform

Documentation

promise-async's API is based on MDN-Promise. typings/promise.lua is the typings with documentation of Promise class.

Summary

Summary up the API different from JavaScript.

<!-- markdownlint-disable MD013 -->
JavaScriptLua
new PromisePromise:new/Promise
Promise.thenPromise:thenCall, then is language keyword
Promise.catchPromise:catch
Promise.finallyPromise:finally
Promise.resolvePromise.resolve
Promise.rejectPromise.reject
Promise.all: Symbol.iterator as iteratorPromise.all: pairs as iterator
Promise.allSettled: Symbol.iterator as iteratorPromise.allSettled: pairs as iterator
Promise.any: Symbol.iterator as iteratorPromise.any: pairs as iterator
Promise.race: Symbol.iterator as iteratorPromise.race: pairs as iterator
async: as keyword at the start of a functionAsync/Async.sync: as a surrounding function
await: as keywordawait/Async.wait as a function
<!-- markdownlint-enable MD013 -->

async

The environment in Async.sync function have been injected some new functions for compatibility or enhancement:

  1. await: A reference of Async.wait function;
  2. pcall: Be compatible with LuaJIT;
  3. xpcall: Be compatible with LuaJIT;

async in JavaScript return Promise object only with single result, but may carry multiple results in Lua. The resolved result of Promise object return by async function will be packed into a table via {...}. However, the result handled by await will be unpacked and return multiple values.

local async = require('async')

local function f()
    return 1, 2, 3
end

-- multiple results are packed into resolved result in Promise
async(f):thenCall(function(v)
    print(v[1], v[2], v[3]) -- output: 1 2 3
end)

-- results returned by `await`
async(function()
    local v1, v2, v3 = await(async(f))
    print(v1, v2, v3) -- output: 1 2 3
end)

uv.run()

Development

Neovim tips

Run tests

make test

Improve completion experience

Following typings/README.md

Customize EventLoop

TODO, refer to loop.lua

Credit

Feedback

License

The project is licensed under a BSD-3-clause license. See LICENSE file for details.