promycycle

A small reactive bookstore, based on promises


Keywords
reactive, rxjs, promise, async
License
ISC
Install
npm install promycycle@0.2.4

Documentation

Logo PromyStore

PromyCycle

By Matias Trujillo Olivares

format size
uncompress 11.20KB
compress 3.11KB
Gzip 1.17KB

NPM

npm install promycycle

It is a library for asynchronous management Inspired by Rxjs, but with promises, it will be useful for the control of calls to the server, worker or others It has by default a series of frequently used utilities at the moment of managing processing asynchronous, this tool perfectly complements PromyStore

Example

/**
* Instance to PromyCycle
*/
var cycle = PromyCycle(); 

cycle
/**
* Limit the number of cycle of execution
*/
.line(1)
/**
* Controls continuity based on an analysis of the argument
*/
.when((argument)=>argument)
/**
* Defines a maximum waiting time for the cycle
*/
.timeout(300)
/**
* Wait x time before moving to the next checkpoint
*/
.delay(300)
/**
* Allows you to control the cycle
*/
.middleware(({next,resolve},argument)=>{
  Promise
    .all([
    next(argument),
    next(argument),
    next(argument),
  ])
    .then(resolve)
})
/**
* Control cycle feedback
*/
.next(()=>{
  return {for:'next'}
})
/**
* Read the cycle return but is not expected by the
*/
.bind((argument)=>{
  console.log(argument)
})
/**
* Subscribe to cyclo if this ends
*/ 
.subscribe(()=>{
  console.log('done');
})
/**
* Triggers the execution of the cycle
* This returns a promise that is resolved 
* at the end of the cycle
*/ 
.dispatch({
  name : 'matias'
})
.then(()=>{
  console.log('end');
})

Explanation

.line()

Allows to control the amount of asynchronous processes in execution, these in turn is released only in case the cycle has finished

  cycle.line(3)

A synchronous queue is generated with a maximum number of 3 lines in execution that can be for example 3 calls ajax

.when(<function|boolean>)

Allows to control the continuity of the cyclo returning if it continues or not through a boolean, if this is true will receive the same argument that has received when, if false the cyclo is solved with the argument resivido also by when

  cycle
  .when(user=>{
    return userLoggedIn(user)
  })
  .next(user=>{
      return {authentication:true}
  })

In this way you can simply ignore requests to the cycle based on a continuity analysis, For example if false returns next will not run, If true, next read the last argument received by next, This is just a simple example

.timeout()

Allows to end the cycle based on a time control, this to executece resolves the cycle and returns the last argument resisted by timeout or the second parameter resivido when creating the timeout

  cycle
  .timeout(1000)
  .middleware(control=>{
      setTimeout(()=>{
          control.next().then(control.resolve)
      },1500)
  })
  .next(()=>{
    return {execution : true}
  })

The middleware is executed but next can not be executed since the cyclo will be solved at the time of the time limit, resolving it with the last argument that rested timeout

.middleware()

Allows to manage a total control over the asynchronous cycle, through the use of properties and methods of the first argument

  • .next(<*>) : Allows to execute the continuity of the cyclo, this in turn returns a promise

  • .resolve(<*>) : Solve the middleware

  • .reject(<*>):Issues an error

  • .follow(<*>): Triggers next solve and reject in chain

  • .argument : Reads the argument delivered to the middleware, This is also delivered to the middleware as second parameter

  • .status : Allows you to know the state of the middleware (Pending, Resolved, Rejected)

  • .instance : The instance of the object invoking the middleware

  cycle
  .middleware(control=>{
      setTimeout(()=>{
          control.follow(userLoggedIn({name:'matias'}))
      },1500)
  })
  .next((state)=>{
    return {execution : state}
  })

.next()

Is executed as a return control point, has the functionality of then within a promise

  cycle
  .next((value)=>{
    return value > 0 ? {value:'positive'} : {value:'negative'}
  })
  
  cycle.dispatch(100).then(console.log)
  cycle.dispatch(-100).then(console.log)

Remember that next always alters the return of the cycle

.bind()

Run as a listener for the cycle, but does not interfere with the

  cycle
  .next((value)=>{
      return value > 0 ? {value:'positive'} : {value:'negative'}
  })
  .bind(()=>{
      console.log('after next');
  })

  cycle.dispatch(100).then(console.log)
  cycle.dispatch(-100).then(console.log)
  

Remember bind never alters the return of the cycle and the errors that proboque do not break the cycle

.subscribe(<done function[,error function[,next function>]])

Subscribe to the cycle process in the following cases

  • done : Is executed at the end of the cycle
  • error: Executes when it emits an error on the part of the cycle
  • next : Is executed when passing from process to process within cyclo

You can use unsubscribe to remove the listener

.dispatch(<*>)

Triggers the execution of the cycle, this in turn returns a promise to know if it has ended or to throw an error

Extending PromyCycle

You can create new functions to be executed as part of the cyclo, and these can be defined as default functions or only belonging to an instance of cyclo

Extending default methods

With a function
PromyCycle.methods.interval = function(middleware,argument){
    setInterval(()=>{
        middleware.follow(middleware.argument)
    },argument)
}

This function is executed only when dispatching the cyclo and when running, use setInterval to generate execution intervals

With a object

you want to alter for example the return when defining the cyclo ud can make use of an object and within the object define 2 middleware and config methods

  • middleware : This subscribes to cyclo as a middleware, so you can use all your methods
  • control : Allows you to set a preconfiguration for the middleware
Extending
PromyCycle.methods.fetch = {
  middleware(middleware,argument,config){
      fetch(config.url,{
          method : config.method,
      })
      .then((response)=> config.toJson ? response.json() : response)
      .then(middleware.follow)
  },
  config(argument,parent){
      return {
        get(url){
            this.url = url;
            this.method = 'GET';
            return this;
        },
        json(){
            this.toJson = true;
            return this;
        },
        parent
      }
  }
}
Instance
  cycle.fetch()
        .get('https://jsonplaceholder.typicode.com/posts')
        .json()
  .parent
  .next((response)=>{
      return response;
  })

  cycle.dispatch({})
In the instance .$set(<string,function,function>)

So you can have custom methods pertaining only to a specific instance

cycle.$set('interval',function(middleware,argument){
    setInterval(()=>{
        middleware.follow(middleware.argument)
    },argument)
})