一、callback
回调函数是最简单的解决方法,这依赖于预先设置好若干回调函数,在程序执行到合适的时候,调用这些回调函数。采用这个方法,我们就把同步操作变成了异步操作,把耗时的任务延迟执行。
function fn1(callback) {
setTimeout(function() {
console.log("1");
callback();
}, 1000);
console.log("2");
}
function fn2() {
console.log("3");
}
fn1(fn2);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
如以上代码执行输出为:
2
1
3
- 1
- 2
- 3
至于为什么遇到耗时长的任务比如setTimeout、读取文件、http请求等会挂起,执行后续的代码,可以查阅javascript的event loop机制,不在本文讨论范围。
二、事件监听
事件监听不取决于代码执行的顺序,而是取决于某个事件是否发生。
例:
document.querySelector("#test").onClick = fn;
document.querySelector("#test").attachEvent("onclick", fn);
document.querySelector("#test").addEventListener("click", fn, false);
- 1
- 2
- 3
此方法容易理解,每个事件可以指定多个回调函数,而且可以“去耦合”,有利于实现模块化。但如果整个程序变成事件驱动的,会导致运行流程非常不清晰。
三、发布/订阅
发布/订阅模式,又叫“观察者模式”。
observe.subscribe("publish1").subscribe("publish2");
publish1.publish(data1);
publish2.publish(data2);
- 1
- 2
- 3
- 4
如上例子,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() {};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
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);
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
then方法返回的是一个新的Promise示例(不是之前那个Promise实例)。因此可以采用链式写法,即then方法后面再调用一个then方法。
catch()
用于Promise发生错误时的回调函数
getJSON('/posts.json').then(function(posts) {
// ...
}).catch(function(error) {
// 处理 getJSON 和 前一个回调函数运行时发生的错误
console.log('发生错误!', error);
});
- 1
- 2
- 3
- 4
- 5
- 6
finally()
用于最后执行,不管Promise最后的状态如何,都会执行的操作。
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});
- 1
- 2
- 3
- 4
all()
将多个Promise实例包装成一个新的Promise实例。
const p = Promise.all([p1,p2,p3]);
- 1
p的状态由p1,p2,p3决定,如果三个都为fulfilled,p的状态才会变为fulfilled;如果有一个为rejected,p的状态就变为rejected。
race()
将多个Promise实例包装成一个新的Promise实例
const p = Promise.race([p1,p2,p3]);
- 1
p的状态由p1,p2,p3决定,如果有一个率先改变状态,p的状态就跟着改变。
resolve()
将现有对象转为Promise对象,状态为fulfilled
Promise.resolve('foo');
//等价于
new Promise(resolve => resolve('foo'));
- 1
- 2
- 3
reject()
将现有对象转为Promise对象,状态为rejected
Promise.reject('error');
// 等价于
new Promise((resolve, reject) => reject('出错了'))
- 1
- 2
- 3
五、Generate
Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同。
Generator 函数的的实现其实是一种叫“协程”的方案,意思是多个线程互相协作,完成异步任务。
它的运行流程大致如下:
- 第一步,协程A开始执行。
- 第二步,协程A执行到一半,进入暂停,执行权转移到协程B。
- 第三步,(一段时间后)协程B交还执行权。
- 第四步,协程A恢复执行。
六、async/await
5分种让你了解javascript异步编程的前世今生,从onclick到await/async
javascript与异步编程 为了避免资源管理等复杂性的问题, javascript被设计为单线程的语言,即使有了html5 worker,也不能直接访问dom. javascri...
--------------------- 本文来自 Leeberber 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/NotEndToLearning/article/details/82564264?utm_source=copy