js异步解决方案

js异步解决方案 常用的解决js异步方法

  1. callback回调,简单粗暴,但是有回调地狱
function a(call){ console.log('方法a返回的结果') call && call() }function b(){ console.log('方法b返回的结果') } // 方法a执行完,执行方法ba(b)

  • 这种写法最大的问题是:如果存在这样的一个业务场景,有三个异步函数A,B,C,其中B的执行需要在A执行结束之后,C的执行需要在B之后,这样的场景模拟成代码就是(jquery中ajax方法为例)
ajax(url, () => { // 处理逻辑 ajax(url1, () => { // 处理逻辑 ajax(url2, () => { // 处理逻辑 }) }) })

  1. 事件监听
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返回的参数')

  1. 发布订阅模式
var salesOffices = {}; salesOffices.clientList = []; // 缓存列表,存放订阅者的回调函数,也就是花名册salesOffices.listen = function( fn ){ // 增加订阅者 this.clientList.push( fn ); // 订阅的消息添加进缓存列表 }; salesOffices.trigger = function(){ // 发布消息 for(var i = 0; i

  • 事件监听是将一个回调函数和事件绑定在一起,触发了相应事件,就会执行相应的回调函数
  • 发布/订阅模式是将订阅函数放入了发布者的订阅者列表中,更新时,遍历订阅者列表,执行所有的订阅者函数
  1. promise
function a(){ console.log('方法a返回的结果') return Promise.resolve() } a().then(()=>{ b() })function b(res){ console.log('方法b返回的结果') }

  1. Generators/ yield
function a(){ console.log('方法a返回的结果') }function *b(){ yield a() console.log('方法b返回的结果') } let b1 = b() b1.next() b1.next()

  1. 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 = https://www.it610.com/article/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 = https://www.it610.com/article/true },err=>{ !hasValue && !hasErr && reject(err) hasErr = true }) } }) }

    推荐阅读