美文网首页
JS异步任务处理的三种解决方案

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

作者: 夏海峰 | 来源:发表于2019-12-10 17:04 被阅读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)
    })
    
    • Promise.all()方法接收一个 promise对象的数组,有且仅当这个数组中所有的promise都成功时,才会执行Promise.all([p1,p2,p3]).then()方法,即代表这三个异步任务都已完成。

    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 })
    

    本篇结束!!!

    相关文章

      网友评论

          本文标题:JS异步任务处理的三种解决方案

          本文链接:https://www.haomeiwen.com/subject/nmyggctx.html