js异步解决方案 常用的解决js异步方法
- 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, () => {
// 处理逻辑
})
})
})
- 事件监听
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
- 事件监听是将一个回调函数和事件绑定在一起,触发了相应事件,就会执行相应的回调函数
- 发布/订阅模式是将订阅函数放入了发布者的订阅者列表中,更新时,遍历订阅者列表,执行所有的订阅者函数
- 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 = 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
})
}
})
}
推荐阅读
- 操作系统|[译]从内部了解现代浏览器(1)
- web网页模板|如此优秀的JS轮播图,写完老师都沉默了
- JavaScript|vue 基于axios封装request接口请求——request.js文件
- vue.js|vue中使用axios封装成request使用
- JavaScript|JavaScript: BOM对象 和 DOM 对象的增删改查
- JavaScript|JavaScript — 初识数组、数组字面量和方法、forEach、数组的遍历
- JavaScript|JavaScript — call()和apply()、Date对象、Math、包装类、字符串的方法
- JavaScript|JavaScript之DOM增删改查(重点)
- javascript|vue使用js-xlsx导出excel,可修改格子样式,例如背景颜色、字体大小、列宽等
- javascript|javascript中的数据类型转换