async await关键字后面的处理

来源:互联网 发布:用sql语句查询年龄在 编辑:程序博客网 时间:2024/06/05 23:56

es7 await 回调函数

在es7 async函数之中,关键词await后的使用普通回调得不到想要的结果。比如:

let content=await fs.readFile(filename);//content=undifined

事实上await后面的函数执行过程是这样的(对比co和yield的连用或者koa@v1.0源码):
1.非promise函数转化成promise,也就是promise.resolve(fn),上面的例子就会是promise.resolve(fs.readFile(filename));显然得不到想要的结果;
2.调用promise.then(function(data){}),这个对比co和yileld连用就是在gen.next(data)这个函数里面调用的,下面是在koa@v1.0的情况:

//fn转化为promisefunction 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);    });  });}
//调用gen.next(res),res就是上面执行回调返回的结果了    function onFulfilled(res) {      var ret;      try {        ret = gen.next(res);      } catch (e) {        return reject(e);      }      next(ret);    }//next函数里调用onfilled,循环下去直到异步任务执行完function next(ret) {      if (ret.done) return resolve(ret.value);      var value = toPromise.call(ctx, ret.value);      if (value && isPromise(value)) return value.then(onFulfilled, onRejected);      return onRejected(new TypeError('You may only yield a function, promise, generator, array, or object, '        + 'but the following object was passed: "' + String(ret.value) + '"'));    }  });

而async await函数相当于gen.next(data)中执行的promise.then(function(data)),这里的data在上面读取文件的例子之中正好是这样:

promise.resolve(fs.readFile(filename));next(fs.readFile(filename)){    //gen.next(data)    promise.then(fs.readFile(filename));}

这样已经清楚得不到的原因了,只需要封装一下原生的函数就可以了,需要两步:

//1.functiontoThunk// ES5版本var Thunk = function(fn){  return function (){    var args = Array.prototype.slice.call(arguments);    return function (callback){      args.push(callback);      return fn.apply(this, args);    }  };};// ES6版本var Thunk = function(fn) {  return function (...args) {    return function (callback) {      return fn.call(this, ...args, callback);    }  };};//2.thunkToPromisefunction 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);    });  });}
fs.readfile(filename,callback)=>Thunk(fs.readfile(filename))=>function (filename) {    return function (callback) {      return fn.call(this, filename, callback);    }=>  function (callback) {      return fn.call(this, filename, callback);    } 

当然,如果不需要通用的话只需要用promise封装一下就行了:
new promise(
(resolve,reject)
=>fs.readfile(filename,function(err,result){
resolve(result)
})
);
基本是是这样了

0 0