javascript - Promises basics. How to promisify async node code? -


i getting started promises , trying use them instead of callbacks avoid callback hell. async functions mix of functions mongodb, redis, bcrypt module, etc. able far:

var insert = q.denodify(db.collection(users).insert); var createcollection = q.denodify(db.createcollection); var sadd = q.denodify(redisclient.sadd); var sismember = q.denodify(redisclient.sismember); var gensalt = q.denodify(bcrypt.gensalt); var hash = q.denodify(bcrypt.hash);  // sanity check // "name" parameter required if(!req.body.name || !isvalidname(req.body.name))      return next(get400invalidnameerror());  // sanity check // "key" optional // if 1 supplied, must valid // key hashed later if(req.body.key){     if(!isvalidkey(req.body.key))         return next(get400invalidkeyerror()); }  // steps: // 1.  // check redis cache see if "name" taken // if yes, return error. if no, continue // 2.  // construct "user" object name = req.body.name // 3.  // req.body.key provided? // if yes, generate salt , hash key. set user.key = hash // if not, continue // 4. // create collection in mongodb same name req.body.name // 5. // add req.body.name cache // 6.  // send response user using res.json() / res.end() sismember(users,req.body.name) .then(createuserobj,errhandler) .then(gensalt(10),errhandler) .then(hash(req.body.key,salt)) .then(createcollection(req.body.name),errhandler) .then(sadd(users,req.body.name),errhandler) .then(insert(user),errhandler) .then(get200usercreated,errhandler) 

what confuses me last part of these functions then()-ed together. have few questions:
1. how can result of 1 async function made available another?
2. how can conditionally decide functions executed? example, want generate salt , hash when req.body.key provided.
3. then() sequence proper?

  1. how can result of 1 async function made available another?

when use promise can resolve or reject it.

var myprom = promise.resolve(1) // simplest promise way 

here if chain then argument equal 1.

myprom.then(function( val ){      console.log(val); // 1     return 33;  }).then(function(passed){      console.log(passed) // 33     return 44;  }).then(function(other){      console.log(other) // 44     if( other > 44 ){         return 'aaa';     } else {         return 'bbb';     } }).then(function(res){      console.log(res) // bbb  }) 

here important thing return promise.
async. part :

// can instanciate new promise object var myprom = new promise(function(resolve , reject){     console.log('we start here');     settimeout(function(){        console.log('we continue here');        resolve( 'time out' );    } , 2000);  }).then(function( val ){      console.log('and end here : ' + val); }); 

the second part then invoked call of resolve in first part.
wait until end, it's "magic" of promise.

the argument passed resolve become argument of next then.
same our first example return important

when :

 sismember(users,req.body.name) 

it same principle timeout.

 var sismember = function(users , req.body.name){      var promisetoreturn = new promise(function(resolve,reject){          var result = ''; // <---do users , req.body.name           // , if ok             if(result){             resolve( result )            } else {// if not ok              reject( result )            }       });      return promisetoreturn; // <-- can chain  })  .then(createuserobj,errhandler)  

the next (after sismember) invoke createuserobj result argument.
become :

 var sismember = function(users , req.body.name){      var promisetoreturn = new promise(function(resolve,reject){          var result = ''; // <---do users , req.body.name           // , if ok             if(result){             resolve( result )            } else {// if not ok              reject( result )            }       });      return promisetoreturn; // <-- can chain  })  .then(function createuserobj( resultofsismember){       var createduser = {} //<--- want resultofsismember       // , return handled next then.      if(everythingisok){         return createduser;      } else {        return promise.reject( 'error during creation');        // handled next error handler or catch      }  } , errhandler ); //<--- provide here error handler  sismember 
  1. how can conditionally decide functions executed? example, want generate salt , hash when req.body.key provided.

different way that.

  1. is then() sequence proper?

no !

you can't call function do.

.then(gensalt(10),errhandler) // <-- invoking result not function // doing that: .then('adekj34llkdf' , errhandler) 

if want add argument use bind

 .then(gensalt.bind(null , 10), errhandler)  // invoke gensalt in null context 10 first argument 

but promise chain provide argument prev function don't have provide !
see example above


once resolved problem, add catch @ end handle error occur. part :

.then(get200usercreated,errhandler)//<--- errhandler prev 

have error handler part :

.then(insert(user),errhandler) 

if have error during insert(user) handled next error handler or catch.

sismember(users,req.body.name) .then(createuserobj,errhandler)// <-- errhandler : sismember .then(gensalt(10),errhandler)// <-- errhandler : createuserobj .then(hash(req.body.key,salt))// <-- missing errhandler : gensalt .then(createcollection(req.body.name),errhandler)// <-- errhandler : hash .then(sadd(users,req.body.name),errhandler)// <-- errhandler createcollection .then(insert(user),errhandler)// <-- errhandler :  .then(get200usercreated,errhandler)// <-- errhandler : insert .catch(errhandler)// <-- errhandler : get200usercreated  

i've wrote error handler here, should take @ that.


Comments

Popular posts from this blog

php - Invalid Cofiguration - yii\base\InvalidConfigException - Yii2 -

How to show in django cms breadcrumbs full path? -

ruby on rails - npm error: tunneling socket could not be established, cause=connect ETIMEDOUT -