关于javascript:js异步解决方案

43次阅读

共计 3815 个字符,预计需要花费 10 分钟才能阅读完成。

js 异步解决方案

罕用的解决 js 异步办法

  1. 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, () => {// 解决逻辑})
    })
})
  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<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)
  • 事件监听是将一个 回调函数 事件 绑定在一起,触发了相应事件,就会执行相应的回调函数
  • 公布 / 订阅模式是将 订阅函数 放入了 发布者 的订阅者列表中,更新时,遍历订阅者列表,执行所有的订阅者函数
  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 = 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
      })
    }
  })
}

正文完
 0