您的位置:首页 > 大数据 > 人工智能

async await关键字后面的处理

2016-07-02 16:26 609 查看

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转化为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);
});
});
}


//调用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.thunkToPromise
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);
});
});
}


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)

})

);

基本是是这样了

$(".MathJax").remove();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  es7-await async-异 函数