The ultimate generator based flow-control goodness for nodejs (supports thunks, promises, etc)

Related tags

Control Flow co
Overview

co

Gitter NPM version Build status Test coverage Downloads

Generator based control flow goodness for nodejs and the browser, using promises, letting you write non-blocking code in a nice-ish way.

Co v4

[email protected] has been released, which now relies on promises. It is a stepping stone towards the async/await proposal. The primary API change is how co() is invoked. Before, co returned a "thunk", which you then called with a callback and optional arguments. Now, co() returns a promise.

co(function* () {
  var result = yield Promise.resolve(true);
  return result;
}).then(function (value) {
  console.log(value);
}, function (err) {
  console.error(err.stack);
});

If you want to convert a co-generator-function into a regular function that returns a promise, you now use co.wrap(fn*).

var fn = co.wrap(function* (val) {
  return yield Promise.resolve(val);
});

fn(true).then(function (val) {

});

Platform Compatibility

co@4+ requires a Promise implementation. For versions of node < 0.11 and for many older browsers, you should/must include your own Promise polyfill.

When using node 0.10.x and lower or browsers without generator support, you must use gnode and/or regenerator.

When using node 0.11.x, you must use the --harmony-generators flag or just --harmony to get access to generators.

Node v4+ is supported out of the box, you can use co without flags or polyfills.

Installation

$ npm install co

Associated libraries

Any library that returns promises work well with co.

  • mz - wrap all of node's code libraries as promises.

View the wiki for more libraries.

Examples

var co = require('co');

co(function *(){
  // yield any promise
  var result = yield Promise.resolve(true);
}).catch(onerror);

co(function *(){
  // resolve multiple promises in parallel
  var a = Promise.resolve(1);
  var b = Promise.resolve(2);
  var c = Promise.resolve(3);
  var res = yield [a, b, c];
  console.log(res);
  // => [1, 2, 3]
}).catch(onerror);

// errors can be try/catched
co(function *(){
  try {
    yield Promise.reject(new Error('boom'));
  } catch (err) {
    console.error(err.message); // "boom"
 }
}).catch(onerror);

function onerror(err) {
  // log any uncaught errors
  // co will not throw any errors you do not handle!!!
  // HANDLE ALL YOUR ERRORS!!!
  console.error(err.stack);
}

Yieldables

The yieldable objects currently supported are:

  • promises
  • thunks (functions)
  • array (parallel execution)
  • objects (parallel execution)
  • generators (delegation)
  • generator functions (delegation)

Nested yieldable objects are supported, meaning you can nest promises within objects within arrays, and so on!

Promises

Read more on promises!

Thunks

Thunks are functions that only have a single argument, a callback. Thunk support only remains for backwards compatibility and may be removed in future versions of co.

Arrays

yielding an array will resolve all the yieldables in parallel.

co(function* () {
  var res = yield [
    Promise.resolve(1),
    Promise.resolve(2),
    Promise.resolve(3),
  ];
  console.log(res); // => [1, 2, 3]
}).catch(onerror);

Objects

Just like arrays, objects resolve all yieldables in parallel.

co(function* () {
  var res = yield {
    1: Promise.resolve(1),
    2: Promise.resolve(2),
  };
  console.log(res); // => { 1: 1, 2: 2 }
}).catch(onerror);

Generators and Generator Functions

Any generator or generator function you can pass into co can be yielded as well. This should generally be avoided as we should be moving towards spec-compliant Promises instead.

API

co(fn*).then( val => )

Returns a promise that resolves a generator, generator function, or any function that returns a generator.

co(function* () {
  return yield Promise.resolve(true);
}).then(function (val) {
  console.log(val);
}, function (err) {
  console.error(err.stack);
});

var fn = co.wrap(fn*)

Convert a generator into a regular function that returns a Promise.

var fn = co.wrap(function* (val) {
  return yield Promise.resolve(val);
});

fn(true).then(function (val) {

});

License

MIT

Comments
  • Add `use()` method for alternative promise implementation

    Add `use()` method for alternative promise implementation

    This PR adds the facility for a user to optionally choose to use a non-native promise implementation for the promises created by co.

    I've seen the debate in the issues here about V8 native promises vs Bluebird, and totally understand the reasoning that it's best to use V8. This PR does not alter the default behaviour of co but allows the user to choose another promise implementation if they want to.

    The PR adds a method co.use():

    co.use()

    var co = require('co');
    
    // normal behaviour
    var p1 = co(function*() {});
    console.log(p1 instanceof Promise); // true
    
    // with co.use()
    var bluebird = require('bluebird');
    co.use(bluebird);
    
    var p2 = co(function*() {});
    console.log(p2 instanceof bluebird); // true
    

    The promise implementation is also accessible as co.Promise.

    co.use() is chainable, so you can initialize co with:

    var co = require('co').use(require('bluebird'));
    

    Why is this needed anyway?

    At present the only way to use bluebird as the promise implementation within co is:

    var bluebird = require('bluebird');
    Promise = bluebird;
    var co = require('co');
    
    var p = co(function*() {});
    console.log(p instanceof bluebird); // true
    

    But this poisons the global variable Promise which isn't good. i.e. it needs support within co to achieve this - it's not possible to implement in a module on top of co.

    Whether people should want to use bluebird over V8 native promises is a matter of debate, but personally I prefer bluebird. But I also very much like co and it'd be great to be able use the two together.

    Completing this PR

    This PR isn't yet complete - needs tests and documentation to finish it.

    But could you please indicate whether you'd be in principle willing to support this? If so, I'll write the tests and docs.

    opened by overlookmotel 34
  • Aggressive Memory Leak

    Aggressive Memory Leak

    I've been able to narrow down an aggressive memory leak I'm experiencing to this:

    Run with: node --harmony --expose-gc filename.js

    var co = require('co');
    
    function* sleep() {
        return new Promise(function(resolve) {
            setTimeout(resolve, 1);
        });
    };
    
    co(function*() {
    
        for(var i = 0; true; ++i) {
            yield sleep();
    
            if (i % 10000 === 0) {
                global.gc();
                console.log(process.memoryUsage());
            }
    
        }
    
    }).then(function() {
        console.log('finished')
    }, function(err) {
        console.log('caught error: ', err.stack);
    });
    

    Sample output:

    { rss: 17420288, heapTotal: 9620736, heapUsed: 3590768 }
    { rss: 44822528, heapTotal: 49288192, heapUsed: 12972200 }
    { rss: 70955008, heapTotal: 58575616, heapUsed: 21688912 }
    { rss: 80048128, heapTotal: 66831104, heapUsed: 30531560 }
    { rss: 89157632, heapTotal: 76118528, heapUsed: 39490184 }
    { rss: 98275328, heapTotal: 85405952, heapUsed: 48445040 }
    { rss: 107368448, heapTotal: 93661440, heapUsed: 57410024 }
    { rss: 116477952, heapTotal: 102948864, heapUsed: 66365712 }
    { rss: 125591552, heapTotal: 112236288, heapUsed: 75330040 }
    { rss: 134684672, heapTotal: 120491776, heapUsed: 84285144 }
    { rss: 143798272, heapTotal: 129779200, heapUsed: 93250072 }
    { rss: 152907776, heapTotal: 139066624, heapUsed: 102205152 }
    { rss: 162000896, heapTotal: 147322112, heapUsed: 111170352 }
    { rss: 171114496, heapTotal: 156609536, heapUsed: 120125032 }
    
    bug batman 
    opened by RHavar 32
  • stop advocating thunks

    stop advocating thunks

    with promises and async/await coming along, i think we should stop advocating thunks. having an entirely separate "co" ecosystem is kind of counter productive for the whole JS ecosystems as a whole. it'll be easier to wrap everything in promises so at least non-co people could use this libraries. co is somewhat a precursor to async/await as well which is promise-based, though i'll still probably still use co since it has a lot more features.

    basically, i want to remove all the "thunkified" libraries from the wiki and primarily only allow promise-based wrappers. this means deprecating libraries like co-fs in favor of a promise-based wrapper like mz

    cc @juliangruber

    opened by jonathanong 28
  • Better error stack

    Better error stack

    Currently

    Error: yield a function, promise, generator, array, or object
    

    has a stack like this

    "stack": [
        "Error: yield a function, promise, generator, array, or object",
        "    at next (/my/project/api/node_modules/koa/node_modules/co/index.js:115:12)",
        "    at Object.<anonymous> (/my/project/api/node_modules/koa/node_modules/co/index.js:56:5)",
        "    at next (/my/project/api/node_modules/koa/node_modules/co/index.js:99:21)",
        "    at Object.<anonymous> (/my/project/api/node_modules/koa/node_modules/co/index.js:56:5)",
        "    at next (/my/project/api/node_modules/koa/node_modules/co/index.js:99:21)",
        "    at Object.<anonymous> (/my/project/api/node_modules/koa/node_modules/co/index.js:56:5)",
        "    at next (/my/project/api/node_modules/koa/node_modules/co/index.js:99:21)",
        "    at Object.<anonymous> (/my/project/api/node_modules/koa/node_modules/co/index.js:56:5)",
        "    at Object.next (/my/project/api/node_modules/koa/node_modules/co/index.js:99:21)",
        "    at /my/project/api/node_modules/koa/node_modules/co/index.js:102:18"
      ]
    

    It's mostly impossible to debug, maybe we can manipulate original stack or attach a new one?

    opened by kilianc 25
  • No documentation on asterisks

    No documentation on asterisks

    There needs to be documentation on asterisks, in one of the first paragraphs of the main Readme.

    It is not at all clear to anyone new to generators in javascript what they are for, or that they are associated in any way with something called "generators", whether they represent new syntax or not, etc.

    The status quo results in unnecessary wasted time for many people.

    Here's some documentation about the topic, but even after reading it, I'm still unclear as to whether these symbols are necessary or not.

    docs 
    opened by taoeffect 18
  • question: how to async with co

    question: how to async with co

    Sometimes generators confuse the soul out of my body and I definitely don't want to be above asking help, so here goes:

    How do you yield in co, within a callback without having the call stack unwrap itself. Also: how do you yield from a callback; passing in a generatorFunction directly stuff breaks.

    This is the function I'm trying to make work:

    function *xhrmw(next) {
      if (!this.url) return yield next;
    
      var opts = {
        url: this.url + qs.stringify(this.query),
        body: this.body,
        method: this.method,
        headers: this.headers
      };
    
      xhr(opts, function(err, res, body) {
        if (err) this.throw(err);
        this.response = res;
        this.body = body;
        // <needs a yield, cannot yield, because not a generator function>
      }.bind(this));
    }
    
    opened by yoshuawuyts 17
  • promise version of co

    promise version of co

    quickly hacked together a promised version of co using bluebird. benchmarks for callback-based co:

              31,859 op/s » promises
              48,958 op/s » thunks
              30,536 op/s » arrays
              33,941 op/s » objects
              26,751 op/s » generators
              50,286 op/s » generators delegated
              26,836 op/s » generator functions
    

    results for this promised based:

              44,526 op/s » promises
              43,249 op/s » thunks
              24,943 op/s » arrays
              26,247 op/s » objects
              37,559 op/s » generators
              50,534 op/s » generators delegated
              37,982 op/s » generator functions
    

    a little slower, but there's room to improve. best of all, though, the code is much simpler since we can remove most of the try/catches

    opened by jonathanong 17
  • Co throws when no callback provided

    Co throws when no callback provided

    Co throws an error when no done callback provided.

    1. There are mostly examples without any callback
    2. Throwing error means it will land as uncaughtException

    First of all its a documentation issue. But I think throwing errors is not a solution at all. Instead done callback should be non optional parameter.

    opened by kof 16
  • Speeding up co by redesigning with OOP - thoughts?

    Speeding up co by redesigning with OOP - thoughts?

    I've been slowly working on a rewrite of co using OOP, see https://github.com/hiddentao/node-generator-perf-tests/tree/master/co-speedup.

    I've been able to increase execution speed across nearly all the different types of yieldables, and particularly so for when yielding promises.

    There is some redundancy in the new version - was necessary for optimising for performance. In any case, I'd be interested to hear your thoughts on it.

    performance 
    opened by hiddentao 15
  • Add fallback generator function test

    Add fallback generator function test

    Hopefully this fixes #192. If function* is not supported, isGeneratorFunction falls back to the old testing method. regenerator runtime uses the displayName property to avoid problems during minification (because GeneratorFunction is renamed during the process).

    Not tested with Traceur...

    opened by madbence 14
  • Broken with mongoose (mpromise)

    Broken with mongoose (mpromise)

    Consider the following example:

    var mongoose = require('mongoose');
    var co = require('co');
    
    mongoose.connect('mongodb://localhost/test');
    
    var User = mongoose.model('User', new mongoose.Schema({
        email: String
    }));
    
    var p = co(function*() {
    //  var users = yield User.find().lean().exec();  // (!)
    });
    
    console.log(p.catch); // (!!!)
    

    In it's current state line (!!!) prints [Function: catch] as it should. But when I uncomment the line (!), then the line (!!!) prints undefined (p becomes "mpromise", the variant mongoose uses).

    That looks odd. The internal call affects the type of promise which is returned from co?

    In both cases console.log(Promise.constructor.toString()); at the end of the code would show the native function, so it doesn't look like mpromise interferes with the global variables. Then why?

    As a consequence, when put in app.use instead of co, such middleware breaks KoaJS (which relies on catch).

    opened by iliakan 14
  • .

    .

    import random import os print("1.شبه ثلاثي بـ(-)") print("2.شبه ثلاثي(.)") print("3.شبه ثلاثي عشوائي") print("4.مخصص") sa = input("اختار:") os.system("COLOR A") if sa == "1":

    print("مكانها؟")
    print("1| (_***)")
    print("2| (*_**)")
    print("3| (**_*)")
    print("4| (***_)")
    da = input("اختار:")
    if da == "1":
        uesr = '_'  # اليوزر المراد التخمين عليه بين النقطتين اكتبه
        chars2 = 'qwertyuiopasdfghjklzxcvbnm0123456789'  # ارقام واحرف لو ترغب
        amount = input('كم عدد اليوزرات ؟')
        amount = int(amount)
    
        length2 = 3
        length2 = int(length2)
    
        for password in range(amount):
            password = ''
    
            for item in range(length2):
                password = ''
            for item in range(length2):
                password += random.choice(chars2)
            bb= uesr + password
            print(bb)
            with open('user.txt', 'a') as x:
                x.write(bb + '\n')
    if da == "2":
        uesr = '_'  # اليوزر المراد التخمين عليه بين النقطتين اكتبه
        chars2 = 'qwertyuiopasdfghjklzxcvbnm0123456789'  # ارقام واحرف لو ترغب
        amount = input('كم عدد اليوزرات ؟')
        amount = int(amount)
    
        length2 = 3
        length2 = int(length2)
    
        for password in range(amount):
            password = ''
    
            for item in range(length2):
                password = ''
            for item in range(length2):
                password = random.choice(chars2)
            for item in range(2):
                password1 = ''
            for item in range (2):
                password1 += random.choice(chars2)
            ba = password + uesr + password1
    
    
            print(ba)
            with open('user.txt', 'a') as x:
                x.write(ba +'\n')
    
    if da == "3":
        uesr = '_'  # اليوزر المراد التخمين عليه بين النقطتين اكتبه
        chars2 = 'qwertyuiopasdfghjklzxcvbnm0123456789'  # ارقام واحرف لو ترغب
        amount = input('كم عدد اليوزرات ؟')
        amount = int(amount)
    
        length2 = 3
        length2 = int(length2)
    
        for password in range(amount):
            password = ''
    
            for item in range(2):
                password = ''
            for item in range(2):
                password += random.choice(chars2)
            for item in range(1):
                password1 = ''
            for item in range(1):
                password1 += random.choice(chars2)
            bd = password + uesr + password1
    
            print(bd)
            with open('user.txt', 'a') as x:
                x.write(bd + '\n')
    if da == "4":
        uesr = '_'  # اليوزر المراد التخمين عليه بين النقطتين اكتبه
        chars2 = 'qwertyuiopasdfghjklzxcvbnm0123456789'  # ارقام واحرف لو ترغب
        amount = input('كم عدد اليوزرات ؟')
        amount = int(amount)
    
        length2 = 3
        length2 = int(length2)
    
        for password in range(amount):
            password = ''
            for item in range(3):
                password = ''
            for item in range(3):
                password += random.choice(chars2)
    
            bc= password + uesr
    
    
            print(bc)
            with open('user.txt', 'a') as x:
                x.write(bc + '\n')
    

    if sa == "2": print("مكانها؟") print("1| .") print("2| *.") print("3| **.") print("4| ***.") da = input("اختار:") if da == "1": uesr = '.' # اليوزر المراد التخمين عليه بين النقطتين اكتبه chars2 = 'qwertyuiopasdfghjklzxcvbnm0123456789' # ارقام واحرف لو ترغب amount = input('كم عدد اليوزرات ؟') amount = int(amount)

        length2 = 3
        length2 = int(length2)
    
        for password in range(amount):
            password = ''
    
            for item in range(length2):
                password = ''
            for item in range(length2):
                password += random.choice(chars2)
            bb= uesr + password
            print(bb)
            with open('user.txt', 'a') as x:
                x.write(bb + '\n')
    if da == "2":
        uesr = '.'  # اليوزر المراد التخمين عليه بين النقطتين اكتبه
        chars2 = 'qwertyuiopasdfghjklzxcvbnm0123456789'  # ارقام واحرف لو ترغب
        amount = input('كم عدد اليوزرات ؟')
        amount = int(amount)
    
        length2 = 3
        length2 = int(length2)
    
        for password in range(amount):
            password = ''
    
            for item in range(length2):
                password = ''
            for item in range(length2):
                password = random.choice(chars2)
            for item in range(2):
                password1 = ''
            for item in range (2):
                password1 += random.choice(chars2)
            ba = password + uesr + password1
    
    
            print(ba)
            with open('user.txt', 'a') as x:
                x.write(ba +'\n')
    
    if da == "3":
        uesr = '.'  # اليوزر المراد التخمين عليه بين النقطتين اكتبه
        chars2 = 'qwertyuiopasdfghjklzxcvbnm0123456789'  # ارقام واحرف لو ترغب
        amount = input('كم عدد اليوزرات ؟')
        amount = int(amount)
    
        length2 = 3
        length2 = int(length2)
    
        for password in range(amount):
            password = ''
    
            for item in range(2):
                password = ''
            for item in range(2):
                password += random.choice(chars2)
            for item in range(1):
                password1 = ''
            for item in range(1):
                password1 += random.choice(chars2)
            bd = password + uesr + password1
    
            print(bd)
            with open('user.txt', 'a') as x:
                x.write(bd + '\n')
    if da == "4":
        uesr = '.'  # اليوزر المراد التخمين عليه بين النقطتين اكتبه
        chars2 = 'qwertyuiopasdfghjklzxcvbnm0123456789'  # ارقام واحرف لو ترغب
        amount = input('كم عدد اليوزرات ؟')
        amount = int(amount)
    
        length2 = 3
        length2 = int(length2)
    
        for password in range(amount):
            password = ''
            for item in range(3):
                password = ''
            for item in range(3):
                password += random.choice(chars2)
    
            bc= password + uesr
    
    
            print(bc)
            with open('user.txt', 'a') as x:
                x.write(bc + '\n')
    

    if sa == "3": uesr = '.' # اليوزر المراد التخمين عليه بين النقطتين اكتبه chars2 = 'qwertyuiopasdfghjklzxcvbnm0123456789' # ارقام واحرف لو ترغب amount = input('كم عدد اليوزرات ؟') amount = int(amount) length2 = 3 length2 = int(length2)

        for password1 in range(amount):
            password1 = ''
            for item in range(length2):
                password1 = ''
            for item in range(length2):
                password1 += random.choice(chars2)
            password35="."+password1
    
    
    
            password2 = ''
    
            for item in range(length2):
                password2 = ''
            for item in range(length2):
                password2 = random.choice(chars2)
            for item in range(2):
                password3 = ''
            for item in range (2):
                password3 += random.choice(chars2)
            password27=password2+"."+password3
    
    
            password4 = ''
    
            for item in range(2):
                password4 = ''
            for item in range(2):
                password4 += random.choice(chars2)
            for item in range(1):
                password5= ""
            for item in range(1):
               password5+=random.choice(uesr)
            for item in range(1):
               password99 = ''
            for item in range(1):
               password99 += random.choice(chars2)
               password9 = password4+password5+password99
    
    
    
            useer = '_'  # اليوزر المراد التخمين عليه بين النقطتين اكتبه
            chars2 = 'qwertyuiopasdfghjklzxcvbnm0123456789'  # ارقام واحرف لو ترغب
    
            for password109 in range(amount):
                password109 = ''
                for item in range(length2):
                    password109 = ''
                for item in range(length2):
                    password109 += random.choice(chars2)
                password350 = "_" + password109
    
                password20 = ''
                for item in range(length2):
                    password20 = ''
                for item in range(length2):
                    password20 = random.choice(chars2)
                for item in range(2):
                    password30 = ''
                for item in range(2):
                    password30 += random.choice(chars2)
                password270 = password20 + "_" + password30
    
                password40 = ''
    
                for item in range(2):
                    password40 = ''
                for item in range(2):
                    password40 += random.choice(chars2)
                for item in range(1):
                    password50 = ""
                for item in range(1):
                    password50 += random.choice(useer)
                for item in range(1):
                    password990 = ''
                for item in range(1):
                    password990 += random.choice(chars2)
                    password90 = password40 + password50 + password990
    
                password60 = ''
                for item in range(3):
                    password60 = ''
                for item in range(3):
                    password60 += random.choice(chars2)
                    password100 = password60 + "_"
    
            mylist = [password9,password27,password35,password100,password90,password270,password350]
            passwordff=""
            ddd = passwordff+random.choice(mylist)
            print(ddd)
            with open('user.txt', 'a') as x:
                x.write(ddd + '\n')
    

    if sa =="4": uesr = '' # اليوزر المراد التخمين عليه بين النقطتين اكتبه chars2 = 'qwertyuiopasdfghjklzxcvbnm1234567890._' # ارقام واحرف لو ترغب amount = input('كم عدد اليوزرات ؟') amount = int(amount)

    length2 = input('ما طول اليوزر الي تبيه؟')
    length2 = int(length2)
    
    for password in range(amount):
        password = ''
    
        for item in range(length2):
            password = ''
        for item in range(length2):
            password += random.choice(chars2)
    
        print(password)
        with open('user.txt', 'a') as x:
            x.write(uesr + password + '\n')
    
    opened by 7cuert 0
  • Added power support for the travis.yml file with ppc64le.

    Added power support for the travis.yml file with ppc64le.

    Added power support for the travis.yml file with ppc64le. This is part of the Ubuntu distribution for ppc64le. This helps us simplify testing later when distributions are re-building and re-releasing.

    opened by sreekanth370 2
  • adding ability to pass classical inheritance object

    adding ability to pass classical inheritance object

    adding ability to pass classical inheritance object

    co(function* () {
      function Human(name, age) {
        this.name = name;
        this.age = age;
      }
    
      Human.prototype.getName = function() {
        return this.name;
      };
    
      Human.prototype.getAge = function() {
        return this.age;
      }
    
      let Asian = function(name, age) {
        Human.call(this, name, age);
        this.country = 'Brunei';
      }
    
      Asian.prototype = Object.create(Human.prototype);
    
      let agus = new Asian('Agus', 29);
    
      let res = yield agus;
    
      console.log(res); // { name: 'Agus', age: 29, country: 'Brunei' }
      console.log(res.getName()); // Agus
      console.log(res.country); // brunei
    })
    .catch(function(e) {
      console.log(e);
    });
    
    
    opened by teknosains 0
Owner
TJ Holowaychuk
TJ Holowaychuk
:surfer: Asynchronous flow control with a functional taste to it

Asynchronous flow control with a functional taste to it λ aims to stay small and simple, while powerful. Inspired by async and lodash. Methods are imp

Nicolás Bevacqua 763 Jan 4, 2023
Callback-free control flow for Node using ES6 generators.

suspend Generator-based control-flow for Node enabling asynchronous code without callbacks, transpiling, or selling your soul. Suspend is designed to

Jeremy Martin 550 Jul 9, 2022
Flow control and error handling for Node.js

NOTE: This project is deprecated and no longer being actively developed or maintained. See Issue #50 for details. StrongLoop zone library Overview The

StrongLoop and IBM API Connect 280 Feb 18, 2022
A solid, fast Promises/A+ and when() implementation, plus other async goodies.

when.js When.js is a rock solid, battle-tested Promises/A+ and when() implementation, including a complete ES6 Promise shim. It's a powerful combinati

The Javascript Architectural Toolkit 3.4k Dec 18, 2022
Map over promises concurrently

p-map Map over promises concurrently Useful when you need to run promise-returning & async functions multiple times with different inputs concurrently

Sindre Sorhus 929 Dec 31, 2022
Helps you write libraries that accept both promises and callbacks.

What is it? promise-breaker makes it easy to write functions that will accept an optional callback, or return a Promise if a callback is not provided.

Jason Walton 83 Aug 11, 2022
P - Toolkit for managing multiple promises

@antfu/p Toolkit for managing multiple promises. Without const items = [1, 2, 3, 4, 5] (await Promise.all(items .map(async i => { const v = awa

Anthony Fu 284 Nov 24, 2022
⚡️The Fullstack React Framework — built on Next.js

The Fullstack React Framework "Zero-API" Data Layer — Built on Next.js — Inspired by Ruby on Rails Read the Documentation “Zero-API” data layer lets y

⚡️Blitz 12.5k Jan 4, 2023
An async control-flow library that makes stepping through logic easy.

Step A simple control-flow library for node.JS that makes parallel execution, serial execution, and error handling painless. How to install Simply cop

Tim Caswell 2.2k Dec 22, 2022
:surfer: Asynchronous flow control with a functional taste to it

Asynchronous flow control with a functional taste to it λ aims to stay small and simple, while powerful. Inspired by async and lodash. Methods are imp

Nicolás Bevacqua 763 Jan 4, 2023
Callback-free control flow for Node using ES6 generators.

suspend Generator-based control-flow for Node enabling asynchronous code without callbacks, transpiling, or selling your soul. Suspend is designed to

Jeremy Martin 550 Jul 9, 2022
Flow control and error handling for Node.js

NOTE: This project is deprecated and no longer being actively developed or maintained. See Issue #50 for details. StrongLoop zone library Overview The

StrongLoop and IBM API Connect 280 Feb 18, 2022
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
Web based application that uses playerctl in it backend to control remotely your audio using the frontend as remote control.

Linux Remote This is a web based application that uses playerctl in it backend to control remotely your audio using the frontend as remote control. Do

Gabriel Guerra 4 Jul 6, 2022
An authorization library that supports access control models like ACL, RBAC, ABAC in Node.js and Browser

Node-Casbin News: still worry about how to write the correct node-casbin policy? Casbin online editor is coming to help! node-casbin is a powerful and

Casbin 2.1k Dec 27, 2022
An authorization library that supports access control models like ACL, RBAC, ABAC in modern JavaScript platforms

Casbin-Core ?? Looking for an open-source identity and access management solution like Okta, Auth0, Keycloak ? Learn more about: Casdoor News: still w

Casbin 6 Oct 20, 2022