共计 3815 个字符,预计需要花费 10 分钟才能阅读完成。
js 异步解决方案
罕用的解决 js 异步办法
- callback 回调,简略粗犷,然而有回调天堂
function a(call){console.log('办法 a 返回的后果')
call && call()}
function b(){console.log('办法 b 返回的后果')
}
// 办法 a 执行完,执行办法 b
a(b)
- 这种写法最大的问题是:如果存在这样的一个业务场景,有三个异步函数 A,B,C,其中 B 的执行须要在 A 执行完结之后,C 的执行须要在 B 之后,这样的场景模仿成代码就是(jquery 中 ajax 办法为例)
ajax(url, () => {
// 解决逻辑
ajax(url1, () => {
// 解决逻辑
ajax(url2, () => {// 解决逻辑})
})
})
- 事件监听
a.on('done', b);
let Event = function (){this.handler = {}
}
Event.prototype.emit = function(eventName,eventDate){let eventHandler = this.handler[eventName]
if(!eventHandler) {return}
eventHandler.map(fn=>fn(eventDate))
}
Event.prototype.on =function(eventName,callback){if(!this.handler[eventName]){this.handler[eventName] = []}
this.handler[eventName].push(callback)
}
let eventCenter = new Event()
eventCenter.on('aEnd',function(res){b(res)
})
function b(res){console.log(res)
}
function a(x){eventCenter.emit('aEnd',x)
}
a('a 返回的参数')
- 公布订阅模式
var salesOffices = {};
salesOffices.clientList = []; // 缓存列表,寄存订阅者的回调函数, 也就是花名册
salesOffices.listen = function(fn){ // 减少订阅者
this.clientList.push(fn); // 订阅的音讯增加进缓存列表
};
salesOffices.trigger = function(){ // 公布音讯
for(var i = 0;i<this.clientList.length;i++){this.clientList[i].apply(this,arguments)
}
};
function a(){console.log('办法 a 返回的后果')
}
function b(res){res()
console.log('办法 b 返回的后果')
}
salesOffices.listen(b)
salesOffices.trigger(a)
- 事件监听是将一个 回调函数 和事件 绑定在一起,触发了相应事件,就会执行相应的回调函数
- 公布 / 订阅模式是将 订阅函数 放入了 发布者 的订阅者列表中,更新时,遍历订阅者列表,执行所有的订阅者函数
- promise
function a(){console.log('办法 a 返回的后果')
return Promise.resolve()}
a().then(()=>{b()
})
function b(res){console.log('办法 b 返回的后果')
}
- Generators/ yield
function a(){console.log('办法 a 返回的后果')
}
function *b(){yield a()
console.log('办法 b 返回的后果')
}
let b1 = b()
b1.next()
b1.next()
- async/await
function fnA(){
return new Promise(resolve=>{...// 异步操作中 resolve})
}
function fnB(){
return new Promise(resolve=>{...// 异步操作中 resolve})
}
function fnC(){
return new Promise(resolve=>{...// 异步操作中 resolve})
}
async function gen(){let resA=await fnA()
let resB=await fnB(resA)
let resC=await fnC(resB)
}
gen()
常见面试题,手写 Promise
const PEDDING = 'PEDDING'
const RESOLVE = 'RESOLVE'
const REJECT = 'REJECT'
const handlePromise = (result, newPromise, resolve, reject) => {if (typeof result === 'object' && result !== null || typeof result === 'function') {
const then = result.then
if (typeof then === 'function') {
then.call(result, r => {handlePromise(r, newPromise, resolve, reject)
}, err => {reject(err)
})
} else {resolve(result)
}
} else {resolve(result)
}
}
class NewPromise {
status = PEDDING
result = undefined
reason = undefined
onResolvedCallBacks = []
onRejectedCallBacks = []
constructor(exc) {
const resolve = result => {if (this.status === PEDDING) {
this.result = result
this.status = RESOLVE
this.onResolvedCallBacks.forEach(fn => fn())
}
}
const reject = reason => {if (this.status === PEDDING) {
this.reason = reason
this.status = REJECT
this.onRejectedCallBacks.forEach(fn => fn())
}
}
exc(resolve, reject)
}
then(onResolve, onReject) {const newPromse = new NewPromise((resolve, reject) => {if (this.status === RESOLVE) {setTimeout(() => {let result = onResolve(this.result)
handlePromise(result, newPromse, resolve, reject)
}, 0);
}
if (this.status === REJECT) {setTimeout(() => {let result = onReject(this.reason)
handlePromise(result, newPromse, resolve, reject)
}, 0);
}
if (this.status === PEDDING) {this.onResolvedCallBacks.push(() => {let result = onResolve(this.result)
handlePromise(result, newPromse, resolve, reject)
})
this.onRejectedCallBacks.push(() => {let result = onReject(this.reason)
handlePromise(result, newPromse, resolve, reject)
})
}
})
return newPromse
}
catch(onReject){return this.then(null, onReject);
}
finally(onFinally) {return this.then(onFinally, onFinally);
}
}
NewPromise.all = function(allp){let list = []
let len = 0
let hasErr = false
return new NewPromise((resolve,reject)=>{for (let i = 0; i < allp.length; i++) {allp[i].then(res=>{list[i] = res
len++
len === allp.length && resolve(list)
},err=>{!hasErr && reject(err)
hasErr = true
})
}
})
}
NewPromise.race = function(allp){
let hasValue = false
let hasErr = false
return new NewPromise((resolve,reject)=>{for (let i = 0; i < allp.length; i++) {allp[i].then(res=>{!hasValue && !hasErr && resolve(res)
hasValue = true
},err=>{!hasValue && !hasErr && reject(err)
hasErr = true
})
}
})
}
正文完
发表至: javascript
2021-12-27