在最开始的时候,js异步编程是一件很痛苦的事,不过随着技术发展,如今写异步已经能够像写同步同样舒服了。es6
回调函数 ===>>> promise ===>>> generater ===>>> async/await编程
dosomething(sucessCallback, errCallback)
复制代码
这种写法在多重异步处理的时候很容易出现回调地狱json
promise最大的好处就是实现了链式调用的写法,并且能够用catch来捕获异常。
不过Promise 对象的错误具备“冒泡”性质,会一直向后传递,直到被捕获为止;并且promise会吞掉错误,不向外部抛出promise
const getJSON = function(url) {
const promise = new Promise(function(resolve, reject){
const handler = function() {
if (this.readyState !== 4) {
return;
}
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
};
});
return promise;
};
getJSON("/posts.json").then(function(json) {
console.log('Contents: ' + json);
}).catch(err => console.log(err));
复制代码
Generator 函数是协程在 ES6 的实现,最大特色就是能够交出函数的执行权,注意它不是语法糖。bash
function* gen(x) {
var y = yield x + 2;
return y;
}
var g = gen(1);
g.next() // { value: 3, done: false }
g.next() // { value: undefined, done: true }
g.throw('出错了');
复制代码
yield以后的跟随的对象或基本类型的值会被自动转化为promise。
generator最麻烦的就是须要本身运行next去执行下一步异步
这是generator+co库的一个es7语法糖,最接近同步的语法。
因为generator须要不断地执行,因而有人写了一个叫co的自执行函数库。async
var co = require('co');
co(gen);
复制代码
这样generator就能够自动地执行了。因而就出现了async/await的写法:异步编程
async function getStockPriceByName(name) {
const symbol = await getStockSymbol(name);
const stockPrice = await getStockPrice(symbol);
return stockPrice;
}
getStockPriceByName('goog').then(function (result) {
console.log(result);
});
复制代码
async后面的函数返回的是一个promise对象,能够用.then的语法。函数
try {
getStockPriceByName()
} catch(err) {
console.log(error)
} finally {
dosomething()
}
复制代码
错误处理方面也更加接近同步的语法。post
只要可以写es6语法,咱们就能够用上async/await的语法来解决异步编程的须要了,这是将会是至关方便的一个体验,也会给后续的人一个更清晰的代码逻辑。