寫在前面的話:
? ? ? ?由于js是單線程的,為了在瀏覽器的交互過程中,不阻塞,提供了異步操作的特性。但是我們?cè)趈s編程中可能會(huì)遇到這樣一種情況:需要等待一個(gè)異步操作執(zhí)行完,并返回結(jié)果,也即是阻塞住當(dāng)前代碼執(zhí)行,接下來的代碼根據(jù)結(jié)果繼續(xù)往下執(zhí)行。
?? ? ?之前在工作中的項(xiàng)目中切實(shí)有這種需求,在一個(gè)文件上傳模塊中,需要計(jì)算上傳文件的md5(文件越大,耗時(shí)越長(zhǎng)),需要在js中hold住計(jì)算,然后將取到的md5傳遞給下面的代碼。最初對(duì)js不甚了解,導(dǎo)致計(jì)算md5總是異步出去操作了,沒有在js的當(dāng)次循環(huán)中執(zhí)行完成,最后用回調(diào)函數(shù)解決了。
? ? ? ?后來看了ES6語法,js新標(biāo)準(zhǔn)提供了諸如generator,promise等新特性,發(fā)現(xiàn)我的這種需求可以用更加簡(jiǎn)潔的方式實(shí)現(xiàn)。下面的例子用到了es6提供的箭頭函數(shù)(匿名函數(shù)的簡(jiǎn)單寫法),generator函數(shù),和promise函數(shù)。
例子:
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
結(jié)果和我想象中的一樣,按照預(yù)先的順序執(zhí)行了a_async,b_async.
而不是想之前在js中一樣,a_async和b_async同時(shí)開始運(yùn)行,b_async取不到a_async的值
相關(guān)資料:http://es6.ruanyifeng.com/#docs/async