Giter VIP home page Giter VIP logo

awaity.js's Introduction

Logo

A functional, lightweight alternative to bluebird.js, built with async / await in mind.


Features

  • Functional utility library for async / await
    Think lodash for promises.

  • Bluebird's powerful collections methods, built with native promises
    Use functions like map, reduce, filter & some to iterate over promises in an intuitive way.

  • Fine-grained Concurrency control
    Resolve all promises at once or in series of 3? the choice is yours.

  • Built to support Tree Shaking from the ground up
    Take what you need and leave the rest.

  • Two flavors: Regular & FP style
    Similar to lodash/fp, Awaity.js comes with additional flavor to support functional composition.
    If it speaks your language, try awaity/fp.

Introduction

Awaity.js is a subset of bluebird.js that focuses only on what's relevant for async / await while using native promises instead, the result is a functional utility library with a minimal footprint. much like lodash, but for promises.

That greatly reduces the library footprint, while bluebird's is 17KB min/gzip, Awaity.js takes only 2KB for the whole lib, and since it built to support tree shaking from the ground up, you can easily pick only what's relevant to you and end up with no more than 1KB.

import { map, props } from 'awaity/esm';

const tasks = await map([1,2,3], async (id) => {
    const res = await fetch(id);
    return res.json();
});

console.log(tasks) // [{...}, {...}, {...}]


// Resolve a promise first
const promise = api.getTasks();
const titles  = await map(promise, (task) => task.title);

// Resolve an array of a promises 
const promisesArray = [ api.getTask(1), api.getTask(2), api.getTask(3)];
const titles = await map(promisesArray, (task) => task.title);

// Resolve an array of a promises + map an object of promises for each
const expendedTasks = await map(promisesArray, (task) => props({
    ...task,
    author: api.getUser(task.authorId),
    comments: api.getCommentsByTask(task.id)
}));

console.log(expendedTasks)
/*
[
    {
        id: 1,
        title: 'Task title..',
        author: { ... },
        comments: [{ ... }, { ... }, { ... }]
    },
    { ... },
    { ... },
    { ... }
]
*/

Installation

npm install awaity

Usage

// Take all
import * as Async from 'awaity';

// Or only what you need
import reduce from 'awaity/reduce';
import some from 'awaity/some';

Or for module bundles (such as webpack, parcel, or rollup), use awaity/esm Which used ES Modules to gain tree shaking support:

import { map, reduce, sum } from 'awaity/esm';

Note: node.js does not support ES Modules out of the box yet.

import fs from 'fs-extra';
import filter from 'awaity/filter';

async function getDirectories(path) {
  const promise = fs.readdir(path);

  return filter(promise, async (file) => {
    const stats = await fs.stat(file);
    return stats.isDirectory();
  });
}

const directories = await getDirectories('.');

FP flavor

Todo: explain what it means.

FP flavor is available under the fp submodule:

import reduce from 'awaity/fp/reduce';
// OR
import { reduce } from 'awaity/esm/fp';

// Just some promises that returns numbers
const promises = [1,2,3].map((i) => Promise.resolve(i));

// By ommiting the last argument,
// we got a function that expects an array of promises
const sum = reduce((total, i) => total + i, 0);

const total = await sum(promises) // 6

Chaining

Awaity.js provides three different kinds of chaining to choose from:

By leveraging Promise's native chaining feature:

import { map } from 'awaity';

const postsWithComments = await Promise.resolve([1,2,3])
    .then((ids) => map(ids, (id) => api.getPostById(id)))
    .then((posts) => map(posts, async (post) => ({
      ...post,
      comments: await api.getCommentsByPostId(post.id)
    })))

Promise chaining + awaity/fp:

import { map } from 'awaity/fp';

const postsWithComments = await Promise.resolve([1,2,3])
    .then(map((id) => api.getPostById(id))
    .then(map(async (post) => ({
      ...post,
      comments: await api.getCommentsByPostId(post.id)
    })))

Using flow

import { map, flow } from 'awaity';

const postsWithComments = await flow([1,2,3], [
    (ids) => map(ids, (id) => api.getPostById(id)),
    (posts) => map(posts, async (post) => ({
      ...post,
      comments: await api.getCommentsByPostId(post.id)
    }))
]);

Using flow + awaity/fp

import { map, flow } from 'awaity/fp';

const postsWithComments = await flow([
    map(ids, (id) => api.getPostById(id)),
    map(posts, async (post) => ({
      ...post,
      comments: await api.getCommentsByPostId(post.id)
    })
], [1,2,3]);

Complex example with promise chain

import { map, reduce, props } from 'awaity/fp';

const posts = await Promise.resolve([1,2,3])
    .then(map((id) => api.getPostById(id)))
    .then(map((post) => props({
        ...post,
        user: api.getUserById(post.userId),
        comments: api.getCommentsByPostId(post.id),
    })))
    .then(reduce(async (results, post) => ({
        ...results,
        [post.id]: post
    })));

Complex example with flow

import { flow, map, reduce, props } from 'awaity/esm/fp';

const posts = await flow([
    map(id => api.getPostById(id)),
    map(post => props({
      ...post,
      user: api.getUserById(post.userId),
      comments: api.getCommentsByPostId(post.id),
    })),
    reduce(async (results, post) => ({
      ...results,
      [post.id]: post
    }), {})
], [1, 2, 3]);

API

Collections

Utilities

FP Mode

Each module also has an equivalate curried version under the fp namespace

import { reduce } from 'awaity/esm/fp';

// FP version is curried
reduce(reducer, initialValue, iterator)
reduce(reducer, initialValue)(iterator)
reduce(reducer)(initialValue)(iterator)


const sum =  reduce((total, i) => total + i, 0);

const total = await sum(promises);

Note: in FP mode, the first argument (the iterable, or promises) is always the last argument.

// Normal Mode: value is the first argument
reduce(iterable, reducer, initialValue);

// FP Mode: value is the last argument
reduce(reducer, initialValue, iterable);

awaity.js's People

Contributors

asfktz avatar imjoehaines avatar kerumen avatar motiz88 avatar rivertam avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

awaity.js's Issues

behavior of `any` on promises that immediately resolve

Hi, Please consider the following code; I passed in promises that "immediately" resolves, I was expecting any() would resolve the first one in the array, but it resolves last one. Is it intended behavior?

const { any } = require('awaity/esm');

const fs = [
  async n => n, // resolves 0
  async n => {
    throw new Error(`n!`);
  },            // rejects 1
  async n => n, // resolves 2
];

const ps = fs.map((f, i) => f(i));

any(ps)
  .then(p => console.log(`any resolved:`, p))
  .catch(err => console.error(`any rejected:`, err));

// any resolved: 2

Compatibility with older environments

Hello,

I was wondering. Would it be possible to use your library on an older runtime, like Node v4?

You use a few async functions for some reason in your library itself. I'm not sure if that choice breaks compatibility with Promise-based but not async/await ready versions.

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.