JS异步任务处理的三种解决方案

2019-12-10  本文已影响0人  夏海峰

需求描述:有三个异步方法,要协同处理同一个任务。该如何判断这个任务在哪个具体的时间点上已完成了呢?

以下3方案可供参考,分别使用到了Promiseasync/awaitProxy观察者模式

三个异步任务方法,如下:

// 第一个异步方法
function asyncFn1(callback) {
  return new Promise((resolve, reject)=>{
    setTimeout(()=>{
      callback && callback(1)
      resolve(1)
    }, 1000)
  })
}

// 第二个异步方法
function asyncFn2(callback) {
  return new Promise((resolve, reject)=>{
    setTimeout(()=>{
      callback && callback(2)
      resolve(2)
    }, 2000)
  })
}

// 第三个异步方法
function asyncFn3(callback) {
  return new Promise((resolve, reject)=>{
    setTimeout(()=>{
      callback && callback(3)
      resolve(3)
    }, 3000)
  })
}

1、使用Promise来实现需求,这也是最简单的实现方案之一,参考代码如下:

Promise.all([asyncFn1(), asyncFn2(), asyncFn3()]).then(res=>{
  console.log('任务成功', res)
}).catch(err=>{
  console.log('任务失败', res)
})

2、使用async/await把异步方法转化成同步调用执行,参考代码如下:

async function doAll() {
  let r1 = await asyncFn1()
  let r2 = await asyncFn2()
  let r3 = await asyncFn3()
  console.log('任务成功', r1, r2, r3)
}

doAll()  // 执行任务

3、使用Proxy封装观察者模式来实现需求,参考代码如下:

// 观察者集合
const observer = new Set()
observer.add((target)=>{
  for(let key in target) {
    if (!target[key]) return
  }
  console.log('任务成功', target)
})

// 可观察的状态数据
const observable = obj => new Proxy(obj, {
  set(target, key, value, receiver) {
    // 更新被观察的状态数据
    const newTarget = Reflect.set(target, key, value, receiver)
    // 执行观察者集合中的观察者方法
    observer.forEach(fn=>fn(target))
    return newTarget
  },
  get(target, key) {
    return target
  }
})
// 当store中的 a、b、c都有值时,表示任务执行成功了。
let store = observable({a:null, b:null, c:null})

// 执行这三个异步方法
asyncFn1(res=>{ store.a = res })
asyncFn2(res=>{ store.b = res })
asyncFn3(res=>{ store.c = res })

本篇结束!!!

上一篇下一篇

猜你喜欢

热点阅读