写在前面的话:
由于js是单线程的,为了在浏览器的交互过程中,不阻塞,提供了异步操作的特性。但是我们在js编程中可能会遇到这样一种情况:需要等待一个异步操作执行完,并返回结果,也即是阻塞住当前代码执行,接下来的代码根据结果继续往下执行。
之前在工作中的项目中切实有这种需求,在一个文件上传模块中,需要计算上传文件的md5(文件越大,耗时越长),需要在js中hold住计算,然后将取到的md5传递给下面的代码。最初对js不甚了解,导致计算md5总是异步出去操作了,没有在js的当次循环中执行完成,最后用回调函数解决了。
后来看了ES6语法,js新标准提供了诸如generator,promise等新特性,发现我的这种需求可以用更加简洁的方式实现。下面的例子用到了es6提供的箭头函数(匿名函数的简单写法),generator函数,和promise函数。
例子:
var a_timeout = () =>{
return new Promise(function (resolve,reject){
setTimeout(function(callback){
console.log('a_timeout start');
console.log('This is a_timeout');
callback('a');
},5000,resolve)
})
};
var b_timeout = function(a_result){
console.log('b_timeout start');
console.log(a_result);
return new Promise(function (resolve,reject){
setTimeout(function(callback){
console.log('This is b_timeout');
callback('b');
},3000,resolve)
})
}
var gen = function* (){
var a_r = yield a_timeout();
var b_r = yield b_timeout(a_r);
};
function run(gen){
var g = gen();
function next(data){
var result = g.next(data);
if (result.done) return result.value;
result.value.then(function(data){
next(data);
});
}
next();
}
run(gen);
输出:
a_timeout start
This is a_timeout
b_timeout start
a
This is b_timeout
结果和我想象中的一样,按照预先的顺序执行了a_async,b_async.
而不是想之前在js中一样,a_async和b_async同时开始运行,b_async取不到a_async的值
相关资料:http://es6.ruanyifeng.com/#docs/async