回调函数转成支持nodejs的generators(yield)写法

by: kelen / 2016-11-18

nodejs支持generator函数,使用yield来执行,由于普通函数不能用 yield 写法,所以只需要简单的把回调函数转换一下,就可以支持yield写法了

首先有一个回调方法

function test (num, cb) {
    if (num > 10) {
        cb(null, "yes");
    } else {
        cb("no");
    }
}

// 调用
test(20, function(err, res) {
    console.log(err, res);
})

Promise封装

可以用promise来封装,实现yield写法

// 把test方法简单转换下,返回promise对象
function test (num) {
    return new Promise(function(resolve, reject) {
        if (num > 10) {
            resolve("yes");
        } else {
            reject("no");
        }
    });
}

可以使用co模块来执行generator

let co = require("co");

co(function*() {
    try {
        var res = yield test(9);
        console.log(res);
    } catch (err) {
        // 捕捉reject抛出的错误
        console.log(err);
    }
})

超简单方法

上面是我想到的方法,但是发现有一种更加方便的方法,直接返回一个新的函数

function test(num) {
  return function(cb) {
    test(num, cb);
  }
}

现在我们可以直接调用,写法简单了许多

var result = yield test(100);

上面写法没法捕获运行错误,可以使用 try..catch 语法

try {
  var result = yield test(100);
} catch (e) {
  console.log('错误消息:',e);
}

之所以可以用上面的写法,看了下co源码,发现原来是co模块内部帮我们把普通回调函数做了一下转换为promise对象

function thunkToPromise(fn) {
  var ctx = this;
  return new Promise(function (resolve, reject) {
    fn.call(ctx, function (err, res) {
      if (err) return reject(err);
      if (arguments.length > 2) res = slice.call(arguments, 1);
      resolve(res);
    });
  });
}


最新发布
热门文章