异步方法有:回调函数、事件监听、发布订阅(观察者模式)、Promise对象、Generator、Async/Await
1. 回调函数
参考setTimeout的原理
容易造成回调地狱(callback hell)
2. 发布订阅
即Publish/Subscribe,发布、订阅模式(也称观察者模式)。常见的有jQuery的自定义事件监听、Node的EventEmitter对象等。
比如在Dom上绑定click事件,相当于订阅了元素的click事件,当元素被点击的时候,他就向订阅者发布这个消息。
很多框架也提供PubSub的类来实现发布订阅模式
3.Promise
JavaScript从ES6开始支持Promise。
Promise是一个特殊的对象,它可以表示异步操作的成功或者失败,同时返回异步操作的执行结果,具有pending, rejected, resolved三种状态。
// 当一切正常时,调用resolve函数;否则调用reject函数
var promise = new Promise(function(resolve, reject){
if ( /* everything turned out fine */ ){
resolve("Stuff worked!");
}else{
reject(Error("It broke"));
}
});
Promise使用then将函数链接起来
function levelOne(value){
var promise, newScore = value + 5;
return promise = new Promise(function(resolve){
resolve(newScore);
});
}
...
startGame.then(levelOne)
.then(function(result){
// result为levelOne函数的返回值
return result;
})
.then(levelTwo)
.then(function(result){
return result;
})
.then(levelThree)
.then(function(result){
...
});
相比传统回调函数而言,Promise代码可读性更高,代码的执行顺序一目了然,但是它的本质还是回调函数。
promise有一个局限就是不能够中止promise链
例如当promise链中某一个环节出现错误之后,已经没有了继续往下执行的必要性,但是promise并没有提供原生的取消的方式,即使在前面已经抛出异常,但是promise链并不会停止。虽然我们可以利用返回一个处于pending状态的promise来中止promise链。
4.Generator
Generator 和 async/await 使用同步的写法来处理异步,明显好于 callback 和 promise,async/await 在语义化上又要比 generator 更强。
5.Async/Await
JavaScript从ES8(即ECMAScript 2017]开始支持Async/Await
本质上,Async/Await只是基于Promise的语法糖,它让我们可以使用同步的方式写异步代码,提高异步代码的可读性,真正抛弃了回调函数。
//同样创建一个Promise对象
function levelOne(value){
var promise, newScore = value + 5;
return promise = new Promise(function(resolve){
resolve(newScore);
});
}
...
//await 只在 async中使用
async function startGame()
{
var currentScore = 5;
currentScore = await levelOne(currentScore);
currentScore = await levelTwo(currentScore);
currentScore = await levelThree(currentScore);
}
网友评论