每日一句
Life is about learning how to dance ine the rain.
释义:人生就是要学会在雨中跳舞。
前言
js是单线程的,就是要等前面的任务执行完才能执行后面的任务。如果任务一多,就会排队,依次执行任务队列,如果一个任务耗时太长就会拖垮整个程序,常见浏览器卡死无反应,无法继续。为了解决这个问题,js的执行模式分为同步和异步。
同步:就是等待前面的任务执行完之后才能执行后面的程序。
异步:前面的任务执行完,执行回调不执行后面的任务,后面的任务不用等待前面的任务是否执行完直接执行后面的任务。
同步和异步的区别:同步会阻塞后续代码的执行,异步不会阻塞后续代码的执行。
异步编程的方案
回调函数:setTimout/seInterval,ajax
ajax(url1, () => {
ajax(url2, () => {
ajax(url3, () => {
...
})
})
})
优点是简单,缺点也很明显就是回调地狱。
事件监听
// fnA执行完,通过触发done事件,执行fnB.
function fnA() {
setTimeout(() => {
// jq方式
fnA.trigger('done')
},1000)
}
function fnB() {
console.log('fnB dong.')
}
fnA.on('done', fnB)
优点是易于理解,可绑多个事件,每个事件可执行多个回调函数。
缺点是整个程序都要变成事件驱动型,运行流程会变得很不清晰。阅读代码的时候,很难看出主流程。
promise/A+
let p = new Promise((resolve, reject) => {
if (true) {
resolve('success')
} else {
reject('reject')
}
})
p.then( value => {
console.log(value)
}, reason => {
console.log(reason)//reject
})
promise不仅能够捕获错误,而且也很好地解决了回调地狱的问题。
缺点:比如无法取消 Promise,错误需要通过回调函数捕获。
async/wait
async function show() {
const res = await say();
console.log('end...', res)
}
function say(){
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('ok...')
resolve(1)
},1000)
})
}
async/await是基于Promise实现的。
async/await与Promise一样,是非阻塞的。
async/await使得异步代码看起来像同步代码
生成器Generators/yied
是ES6 提供的一种异步编程解决方案
function *foo(x) {
let y = 2 * (yield (x + 1))
let z = yield (y / 3)
return (x + y + z)
}
let it = foo(1)
console.log(it.next()) // => {value: 2, done: false}
console.log(it.next(3)) // => {value: 2, done: false}
console.log(it.next(5)) // => {value: 12, done: true}
x=1, y=6,z=5
首先 Generator 函数调用和普通函数不同,它会返回一个迭代器
当执行第一次 next 时,传参会被忽略,并且函数暂停在 yield (x + 1) 处,所以返回 1 + 1 = 2
当执行第二次 next 时,传入的参数3就会被当作上一个yield表达式的返回值,如果你不传参,yield 永远返回 undefined。此时 let y = 2 * 3,所以第二个 yield 等于 6 / 3 = 2
当执行第三次 next 时,传入的参数5就会被当作上一个yield表达式的返回值,所以 z = 5, x = 1, y = 6,相加等于12
发布订阅
实现思路
- 创建一个对象
- 在该对象上创建一个缓存列表(调度中心)
- on 方法用来把函数 fn 都加到缓存列表中(订阅者注册事件到调度中心)
- emit 方法取到 arguments 里第一个当做 event,根据 event 值去执行对应缓存列表中的函数(发布者发布事件到调度中心,调度中心处理代码)
- off 方法可以根据 event 值取消订阅(取消订阅)
- once 方法只监听一次,调用完毕后删除缓存函数(订阅一次)
观察者模式
观察者模式指的是一个对象(Subject)维持一系列依赖于它的对象(Observer),当有关状态发生变更时 Subject 对象则通知一系列 Observer 对象进行更新。
在观察者模式中,Subject 对象拥有添加、删除和通知一系列 Observer 的方法等等,而 Observer 对象拥有更新方法等等。