najam najam - 5 months ago 15
Javascript Question

converting convention node.js function with callback to generators and yield

I am new to koa.js and liked it very much, started a project with it. i need to use twilio for sms sending.

most calls for twilio package follow this structure.

public.get('/najam', function *(){
this.body = "hello from najam";
//yeild before c.sendSms or inside callback?
c.sendSms({
to:'YOUR_PHONE',
}, function(e, m) {
if (!e) {
//yeild here?
}
});
});


how can i modify it to put it inside generator function and at what point i will use yield keyword?

If your answer suggesting to use Co library please provide me example with code and bit explanation.

Answer

Just wrap callback-based interfaces with a Promise so that you can yield it in the route.

function sendSms(toPhone, textMessage) {
  return new Promise(function(resolve, reject) {
    c.sendSms({ to: toPhone, message: textMessage }, function(err, result) {
      if (err) return reject(err);
      resolve(result);
    });
  });
}

Now you can yield it inside of the route. If it throws an error (like if the network is down), then Koa's default error handler will catch it and turn it into a 500 error.

public.get('/najam', function *(){
    this.body = "hello from najam";
    yield sendSms('YOUR_PHONE', 'SOME_MESSAGE');
});    

Or you can try/catch it yourself if you want to handle the error in some specific way:

public.get('/najam', function *(){
    this.body = "hello from najam";
    var result;
    try {
      result = yield sendSms('YOUR_PHONE', 'SOME_MESSAGE');
    } catch(err) {
      // Maybe we just wanna log the error to a server before rethrowing
      // it so Koa can handle it
      logError(err);
      throw err;
    }
});    

When wrapping something with a Promise, it's just a matter of calling reject(err) when there's an error and resolve(result) when it successfully completes.

Comments