03月29, 2018

【译】Object.observe 已死,Mobx.observe 将永生

Object.observe已经官方声明废弃,当然这也是在情理之中的,因为这个属性不可预测性太高。但是这并不意味着拥有一个可以观察的对象是一件坏事。事实上,可观察对象是一个非常强大的概念。别担心,MobX 这个库可以实现高效观察对象。最重要的是,不像 'Object.observe' 属性,它可以流畅的运行在ES5环境中。当然 MobX 的 api 与 'Object.observe' 是很相似的。眼见为实,接下来我们试试看:

// JSBin: http://jsbin.com/kekoli/edit?js,console
import {observable, observe} from "mobx";

const person = observable({
    firstName: "Maarten",
    lastName: "Luther"
});

const disposer = observe(person, (change) => {
    console.log(`${change.type} '${change.name}' from '${change.oldValue}' to '${change.object[change.name]}'`);
});

person.firstName =  "Martin";
// Prints: 'update 'firstName' from 'Maarten' to 'Martin'

disposer();
// Ignore any future updates

上述代码,'observable' 会把你传入的对象进行修饰,以便 MobX 可以对传入的对象进行观察。从这里开始,我们就可以使用 'observe' 来订阅对象未来的改变。

所以它是怎么运行的呢?

observable 这个方法会为对象的所有属性创建 setter 然后用于数组的索引。这样就可能检测到属性变化了。这种方法比 脏检查 更加高效。实际上,变化可以被同步的检测和报告。这使得观察者更加容易预测并且容易调试。当然,你也可以根据需要,随时在观察者的顶部添加异步层。默认情况下,分配给可观察结构的新值也会被观察。MobX实现了深度观察。

'observer'外谈

通过使用'mobx.observe',你可以反复观察对象和数组的变化。但事实上,'observer'是一个很低级的做法。MobX 提供了更强大的概念!MobX 是一个 透明函数式响应式编程库(Transparent Functional Reactive Programming - TFRP)。当数据结构发生改变时,它会创建自动计算的函数。MobX会分析是函数的数据依赖 然后 为你订阅可观察的数据结构。举个例子:

// JSBin: http://jsbin.com/xoyehi/edit?js,console
import {observable, autorun} from "mobx";

const todos = observable([{
    title: "Find napkin",
    completed: false
}]);

autorun(() =>
    console.log(todos
        .filter(todo => !todo.completed)
        .map(todo => todo.title)
        .join(", "))
);
// Prints: 'Find napkin'

todos[1] = {
    title: "Sneeze",
    completed: false
};
// Prints: 'Find napkin, Sneeze'

todos[0].completed = true;
// Prints: 'Sneeze'

todos[1].title = 'Ha.. ha... ha....'
// Prints: 'Ha.. ha... ha.... '

todos[0].title = "Foobar";
// (doesn't print)

正如你看到的,事实上,'autorun' 是一种比 'observe' 更强大的概念。只要当需要的时候,它会自动运行所定义的函数。很显然,'autorun'实现了更深层的订阅。它会自动订阅新的待办事项。当 ToDo 列表不再与 'autorun'定义的函数关联时,它会自动取消对 ToDo 列表的订阅。这是一个非常强大的概念,可以自动保留任何类型的派生数据,有效的实现数据同步。

所以,如果你需要以一种可靠的方式订阅复杂的数据机构,那就试试MobX吧。

局限性

使用 'mobx.observable' 创建可观察数据结构是一种很强大的方式。然鹅,由于ES5的限制,还是有两件事情需要注意:

  1. MobX不会自动检测 在已有对象上添加一个新属性 的行为。解决这个问题,你可以使用 'undefined' 来提前声明属性, 或者使用 'mobx.extendObserable' 这个方法来添加属性, 又或者可以使用 'mobx.map()' 方法创建一个 ES6 的 Map 对象

  2. 可观察的数组并不是真正意义上的数组,实际上它是一个对象。它们只是表现上像普通数组但不确保其他库可以将它识别成为数组。这种情况下,只需要将数组 'slice()' 后传递给其他库就可以了。

原文链接:https://medium.com/@mweststrate/object-observe-is-dead-long-live-mobservable-observe-ad96930140c5

本文链接:https://www.imwineki.cn/post/MobxobserveTranslate.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。