javascript 异步编程总结

javascript 是单线程的,即一次只能完成一个任务,如果有多个任务,则必须排队执行。这种模式实现简单,但如果有一个比较耗时的任务,会拖延整个程序的执行。

一、callback

回调函数是最简单的解决方法,这依赖于预先设置好若干回调函数,在程序执行到合适的时候,调用这些回调函数。采用这个方法,我们就把同步操作变成了异步操作,把耗时的任务延迟执行。

function fn1(callback) {
	setTimeout(function() {
		console.log("1");
		callback();
	}, 1000);
	
	console.log("2");
}

function fn2() {
	console.log("3");
}

fn1(fn2);

如以上代码执行输出为:

2
1
3

至于为什么遇到耗时长的任务比如setTimeout、读取文件、http请求等会挂起,执行后续的代码,可以查阅javascript的event loop机制,不在本文讨论范围。

二、事件监听

事件监听不取决于代码执行的顺序,而是取决于某个事件是否发生。
例:

document.querySelector("#test").onClick = fn;
document.querySelector("#test").attachEvent("onclick", fn);
document.querySelector("#test").addEventListener("click", fn, false);

此方法容易理解,每个事件可以指定多个回调函数,而且可以“去耦合”,有利于实现模块化。但如果整个程序变成事件驱动的,会导致运行流程非常不清晰。

三、发布/订阅

发布/订阅模式,又叫“观察者模式”。

observe.subscribe("publish1").subscribe("publish2");

publish1.publish(data1);
publish2.publish(data2);

如上例子,observe订阅了publish1和publish2,当publish1和publish2发布后,observe将会执行observe(data1),observe(data2)。

四、Promise

Promise是异步编程的一种解决方案,比传统的回调和事件更加强大。Promise简单说就是一个容器,里面保存着某个未来才会结束的事件结果。从语法上来说它是一个对象,可以获取异步操作的消息。
Promise有如下api:

promise.then = fucntion() {};
promise.catch = function() {};
promise.finally = function() {};
promise.all = function() {};
promise.race = function() {};
promise.resolve = function() {};
promise.reject = function() {};
promise.try = function() {};

Promise有三种状态,pending(进行中)、fulfilled(已成功)和rejected(已失败)。Promise对象的状态改变,只有两种可能,从pending变为fulfilled,从pending变为rejected。一旦发生,状态就凝固了,会一直保持这个结果。

then()

为 Promise 实例添加状态改变时的回调函数

getJSON("/post/1.json").then(function(post) {
  return getJSON(post.commentURL);
}).then(function funcA(comments) {
  console.log("resolved: ", comments);
}, function funcB(err){
  console.log("rejected: ", err);
});

then方法返回的是一个新的Promise示例(不是之前那个Promise实例)。因此可以采用链式写法,即then方法后面再调用一个then方法。

catch()

用于Promise发生错误时的回调函数

getJSON('/posts.json').then(function(posts) {
  // ...
}).catch(function(error) {
  // 处理 getJSON 和 前一个回调函数运行时发生的错误
  console.log('发生错误!', error);
});

finally()

用于最后执行,不管Promise最后的状态如何,都会执行的操作。

promise
	.then(result => {···})
	.catch(error => {···})
	.finally(() => {···});

all()

将多个Promise实例包装成一个新的Promise实例。

const p = Promise.all([p1,p2,p3]);

p的状态由p1,p2,p3决定,如果三个都为fulfilled,p的状态才会变为fulfilled;如果有一个为rejected,p的状态就变为rejected。

race()

将多个Promise实例包装成一个新的Promise实例

const p = Promise.race([p1,p2,p3]);

p的状态由p1,p2,p3决定,如果有一个率先改变状态,p的状态就跟着改变。

resolve()

将现有对象转为Promise对象,状态为fulfilled

Promise.resolve('foo');
//等价于
new Promise(resolve => resolve('foo'));

reject()

将现有对象转为Promise对象,状态为rejected

Promise.reject('error');
// 等价于
new Promise((resolve, reject) => reject('出错了'))

五、Generate

Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同。
Generator 函数的的实现其实是一种叫“协程”的方案,意思是多个线程互相协作,完成异步任务。
它的运行流程大致如下:

  • 第一步,协程A开始执行。
  • 第二步,协程A执行到一半,进入暂停,执行权转移到协程B。
  • 第三步,(一段时间后)协程B交还执行权。
  • 第四步,协程A恢复执行。

六、async/await

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值