异步编程的方式

Promise的用法

异步编程的四种方式

回调函数

获取异步任务的结果。假设有两个函数f1和f2,f2需要等待f1的执行结果,如果f1是一个需要很长时间来执行的代码,则需要考虑改写f1,将f2作为f1的回调函数

1
2
3
4
5
6
7
8
function f1(callback){
setTimeout(function(){
// f1的任务代码
callback();
}, 1000)
}

f1(f2) // 执行代码会变成这样

采用回调函数的方式,将同步操作变成异步,f1不会阻塞程序运行,相当于先执行程序的主要逻辑,将耗时的操作推迟执行

它的优点是简单、容易理解和部署,缺点是不利于代码的阅读和维护,各个部分之间高度耦合,流程会很混乱,而且每个任务只能指定一个回调函数。

事件监听

任务执行不取决于代码的顺序,而是事件是否发生(采用jQuery的写法)

1
f1.on('done', f2);  // 当f1发生done事件,就执行f2

再改写f1中的代码

1
2
3
4
5
6
function f1(){
setTimeout(function(){
// f1任务代码
f1.trigger('done') // 执行完成后,立即触发done事件,从而开始执行f2
}, 1000)
}

它的优点是比较容易理解,可以绑定多个事件,每个事件可以指定多个回调函数,而且可以解耦,有利于实现模块化。缺点是整个程序都要变成事件驱动型,运行流程会变得很不清晰。

发布订阅模式

又称为观察者模式,将上面的事件理解成信号,假设有个信号中心,某个任务执行完就向中心发布一个信号,其他依赖于这个任务的可以向信号中心订阅这个信号,从而知道什么时间自己开始执行

1
jQuery.subscribe("done", f2);  // f2向信号中心jQuery订阅done信号

接着对f1进行改写

1
2
3
4
5
6
function f1(){
setTimeout(function(){
// f1的任务代码
jQuery.publish("done"); // f1执行完后,向信号中心发送done信号,从而触发f2执行
}, 1000);
}

与事件监听性质十分类似,但优于前者,我们可以通过信号中心查看设置了多少个信号,以及每个信号有多少个订阅者,从而监控程序运行

Promise对象

定义:(参考阮一峰教程)

Promise 是一个对象,对象里存储一个状态,这个状态是可以随着内部的执行转化的,为以下三种状态之一:等待态(Pending)、完成态(Fulfilled)、拒绝态(Rejected)。

一开始,我们先设置好等状态从 pending 变成 fulfilled 和 rejected 的预案(当成功后我们做什么,失败时我们做什么)。

Promise 启动之后,当满足成功的条件时我们让状态从 pending 变成 fulfilled (执行 resolve);当满足失败的条件,我们让状态从 pending 变成 rejected(执行 reject)

promise是回调的一种形式,同时也是一个事务管理器。他的作用是将各种内嵌回调的事务用流水形式表达,其目的是为了简化编程,让代码逻辑更加清晰。

1、then的链式用法(结合jQuery的写法)

1
2
3
$.ajax({
url:'/xxx',
}).then(successFn,errorFn).then(successFn2,errorFn2)

2、自己生成一个Promise对象

1
2
3
4
5
6
7
8
9
10
function returnPromise(){
return new Promise(function(resolve, reject){
setTimeout(()=>{
resolve() // 成功后调用
reject() // 失败后调用
}, 5000)
})
}

returnPromise().then(result)

3、async和await(两者的关系是相互依赖,通过await模拟同步代码)

1
2
3
4
5
function returnPromise(){
... ...
}

var result = await returnPromise() //await的用法就是将异步代码写成同步的,await左边是同步,右边是异步结果,有了await它会等待异步的结果,从而改变整个代码的执行顺序,await后接一个返回promise的函数

4、try…catch

捕获报错信息,catch是一个没有成功函数的失败函数,可以想象成then的语法糖

1
2
3
4
5
6
7
8
9
10
function returnPromise(){
... ...
}

try{
var promise = await xxx()
console.log('没出错')
}catch(error){
console.log('异常了')
}

0%