JavaScript中是否可写出同时间执行的方法的调用?

在JavaScript 中,如下示例:

// es2015
// 可以参考 Backbone.View
class View {
    constructor() {
        this._data = {
            text: ''
        };
        this._html = '';
    }
    setData(data) {
        this._data = data;
        return this;
    }
    render() { // 牢记纯函数式思维: 输入 => 输出
        return this._html = '<p>' + this._data.text + '</p>';
    }
}

// 建立一个视图
var view = new View();
// 给视图灌入数据, 基于这份数据来渲染视图
view.setData({text: '数据1'}).render();
// 给视图灌入新数据, 不管三七二十一, 重新渲染视图
view.setData({text: '数据2'}).render();
view.setData({text: '数据N'}).render();

我们在调用代码的时候:
view.setData({text: '数据1'}).render();
明显,这个是同步操作,先执行setData()再执行render()
请问下,1.我们是否可以在JS的类中设计可以同时异步执行的方法呢?在调用时候,两方法都一起执行。2.再加一个final函数,让它们都执行完成之后,会最终触发final函数。类似:
view.setData({text: '数据1'}).render().finally((...)=>{...})

阅读 2.5k
5 个回答

就我理解的意思,类似柯里化的思路,可以参考一下我的相关博文。
这下面是一种思路,具体要以实际需求调整。

class Test {
  data = {};
  __promises = {};
  setData(obj) {
    this._addPromise((res, rej) => {
      // 为了测试效果,使用了setTimout模拟异步
      setTimeout(() => {
        console.log('setData---')
        this.data = Object.assign(this.data, obj)
        res(1)
      }, 1000)
    })
    
    //...
    return this
  }
  render() {
    this._addPromise((res, rej) => {
      setTimeout(() => {
        console.log('render---:', this.data)
        res(2)
        // this.data = Object.assign(this.data, obj)
      })
      
    })
    
    return this
  }
  _addPromise(fn) {
    const key = new Date().getTime() + ( Math.random() * Math.pow(10,8)) ;
    const prm = new Promise((res, rej) => {
      return fn(res, rej)
    })
    this.__promises[key] = prm
    // 避免key被即时销毁,promise.all注册finally时保证prm存在__promises当中
    setTimeout(() => {
      prm.finally(() => {
        delete this.__promises[key]
      })
    })
  }
  finally(fn) {
    Promise.all(Object.values(this.__promises)).finally( () => fn(this))
  }
}

view.setData({text: '数据1'}).render();表面上是同步其实是异步操作, 因为DOM渲染是宏任务, render时是异步的
JS是单线程, 不能像java等控制多个线程
第一个问题: 可以依次创建多个异步任务, 但具体执行时一定是依次执行的, 可以看下事件循环https://segmentfault.com/a/11...

第二个问题: 可以, 使用Promise.all

就这个例子来说,不是很明白。 先setData,然后再render不是很合理吗? 如果没有新数据的setData,为什么要render。

然后,要一起执行的话,是没法做到的,js没有那种多线程。除非使用worker来做,但是这样又很怪。就这个例子来说很怪。

至于都完成后再执行后面的逻辑,那就用promise.all。

Promise.all([new Promise((resolve) => {
   return setTimeout(() => {
      console.log('第一个方法完成');
      resolve(1);
   }, 300);
}), new Promise((resolve) => {
   return setTimeout(() => {
      console.log('第二个方法完成');
      resolve(2);
   }, 500);
})]).then((res) => {
   console.log('全部完成:', res)
})

js是单线程,无论同步和异步,代码都是依次执行。

推荐问题
宣传栏