"immutable данные в js приложениях", Дмитрий Кунин, moscowjs...

45
Immutable Data Неизменяемые данные в приложении: что, зачем и как логитип moscow js Дмитрий Кунин, AT-Consulting

Upload: moscowjs

Post on 16-Jul-2015

230 views

Category:

Software


0 download

TRANSCRIPT

Page 1: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Immutable DataНеизменяемые данные в приложении:

что, зачем и каклогитип moscow js

Дмитрий Кунин, AT-Consulting

Page 2: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Что это такое?

2 / 45

Page 3: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Immutable + Persistent

3 / 45

Page 4: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Принцип работы

var list = Immutable.List.of(1,2,3);var list2 = list.push(4);

console.log(list.toJS()) // [1,2,3] console.log(Immutable.is(list,list2)) // false

4 / 45

Page 5: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Принцип работы

List.prototype.push = function(value){ // Делаем клон var clone = deepCopy(this); // Меняем значение в клоне clone[clone.length] = value; // Вовзращаем клон return clone; }

5 / 45

Page 6: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

var list = [];for(var i=0;i < 1000000;i++) { list.push(i);}

vanilla: 83 ms

var list = mori.vector();for (var i=0; i < 1000000; i++) { mori.conj(list, i);}

mori: 288 ms

Скорость работы

6 / 45

Page 7: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Направленный ациклический граф

7 / 45

Page 8: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

8 / 45

Page 9: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

9 / 45

Page 10: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

10 / 45

Page 11: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

11 / 45

Page 12: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

12 / 45

Page 13: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

13 / 45

Page 14: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

14 / 45

Page 15: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Готовые библиотеки

immutable.jsmoriseamless-immutableimmutatopimsetitexoancient-oak

15 / 45

Page 16: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Зачем использовать?

16 / 45

Page 17: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Зачем использовать?

Решать проблемы!

17 / 45

Page 18: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Мутирующие объекты могут мутировать:)))

var identity = "Федор";...identity = "Федор Петрович";...identity = "Косой";

18 / 45

Page 19: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Интерфейс долженследить за изменениями

19 / 45

Page 20: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Слушатели событийvar userData = { name:"Федор", online:true, profilePic: "/url/user1.png" };

Object.observe(userData, function(changes){ rerenderProfile();});

userData.name = "Федор Петрович";userData.online = false;userData.profilePic = "/newurl/user2.png";

20 / 45

Page 21: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

var userData = { ... };Object.observe(userData, ... );userData.name.nickname = "Косой"; // Изменения не замечены

21 / 45

Page 22: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

"Грязная" проверка Грязные танцыvar userData = { dirty: false, _raw: { name: "Федор Петрович", online: true, profilePic: "/url/user1.png"}, get: function(key){ return this._raw[key] }, set: function(key, newValue){ this._raw[key] = newValue; this.dirty = true; }}

22 / 45

Page 23: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

funtion renderProfile(data) { if(!data.dirty) return; data.dirty = false; ...}

userData.set("online", true);

renderProfile(userData); // ok

23 / 45

Page 24: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

funtion renderProfile(data) { if(!data.dirty) return; data.dirty = false;}

funtion renderContactItem(data) { if(!data.dirty) return; data.dirty = false;}

data.set("online", true);

renderProfile(userData); // okrenderContactItem(userData); // dirty = false; no render

24 / 45

Page 25: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Сравнение Immutable объектов / списковvar user1 = Immutable.Map({ name: "Федор Петрович", online: true, profilePic: "/url/user1.png"});

25 / 45

Page 26: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Сравнение Immutable объектов / списковvar user1 = Immutable.Map({ name: "Федор Петрович", online: true, profilePic: "/url/user1.png"});

var user2 = user1.set("name", "Косой");console.log(Immutable.is(user1, user2)); // false

26 / 45

Page 27: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Сравнение Immutable объектов / списковvar user1 = Immutable.Map({ name: "Федор Петрович", online: true, profilePic: "/url/user1.png"});

var user2 = user1.set("name", "Косой");console.log(Immutable.is(user1, user2)); // false

var user3 = user2.set("name", "Федор Петрович");console.log(Immutable.is(user1, user3)); // true

27 / 45

Page 28: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Глубокое сравнениеvar user1 = Immutable.Map({ skills: Immutable.Map({str: 23, int: 18, luck: 99}), category: Immutable.Map({gentelaman: true})});

28 / 45

Page 29: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Глубокое сравнениеvar user1 = Immutable.Map({ skills: Immutable.Map({str: 23, int: 18, luck: 99}), category: Immutable.Map({gentelaman: true})});var user2 = user1.setIn(["skills", "int"], 0);

Immutable.is(user2 , user1)

29 / 45

Page 30: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Глубокое сравнениеvar user1 = Immutable.Map({ skills: Immutable.Map({str: 23, int: 18, luck: 99}), category: Immutable.Map({gentelaman: true})});var user2 = user1.setIn(["skills", "int"], 0);

Immutable.is(user2 , user1) Immutable.is(second.get("skills") , first.get("skills")) //false

30 / 45

Page 31: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Глубокое сравнениеvar user1 = Immutable.Map({ skills: Immutable.Map({str: 23, int: 18, luck: 99}), category: Immutable.Map({gentelaman: true})});var user2 = user1.setIn(["skills", "int"], 0);

Immutable.is(user2 , user1) Immutable.is(second.get("skills") , first.get("skills")) //falseImmutable.is(second.get("category"), first.get("category")) //true

31 / 45

Page 32: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Плюшки

32 / 45

Page 33: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Отсутствие побочных эффектов

function updateValueAndLog(updateFunction) { var data = {name: "Федор"}; updateFunction(data); console.log(data); // ?}

33 / 45

Page 34: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Отсутствие побочных эффектов

function updateValueAndLog(updateFunction) { var data = {name: "Федор"}; updateFunction(data); console.log(data); // ?}

var user = Immutable.Map({ name: "Федор Петрович", online: true, profilePic: "/url/user1.png"});

var userClone = user; 34 / 45

Page 35: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Практически бесплатныйundo/redo

35 / 45

Page 36: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

0:00

36 / 45

Page 37: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Как пользоваться?

37 / 45

Page 38: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Массивыvar list1 = Immutable.List.of(1, 2);assert(list1.size === 2);

var list2 = list1.push(3, 4, 5);assert(list2.size === 5);

var list3 = list2.unshift(0);assert(list3.size === 6);

var list4 = list1.concat(list2, list3); assert(list4.size === 13);

assert(list4.get(0) === 1);

38 / 45

Page 39: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Объектыvar user1 = Immutable.Map({ name: "Федор Петрович", online: true, profilePic: "/url/user1.png"});

var user2 = user1.set("name", "Косой");

user1.get("name"); // "Федор Петрович"user2.get("name"); // "Косой"

39 / 45

Page 40: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Принимает и возвращает обычные JSобъектыvar user1 = Immutable.Map({ name: "Федор Петрович", online: true, profilePic: "/url/user1.png"});

var stat = { name:"Косой", age: 37 };var user2 = user1.merge(stat);

console.log(user2.toJS()) // { name: "Косой", // online: true, // profilePic: "/url/user1.png",// age: 37 } 40 / 45

Page 41: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Многое другое

StackOrderedMapSetOrderedSetRecord

41 / 45

Page 42: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Групповые операцииvar traits1 = Immutable.List.of("communication","luck","skill"var traits2 = traits1.withMutations(function (traits) { traits.push("dexterity").push("power").push("speed");});assert(traits1.size === 3);assert(traits2.size === 6);

42 / 45

Page 43: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Стоит пощупать вследующем проекте?

43 / 45

Page 44: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Стоит пощупать вследующем проекте?

Да!

44 / 45

Page 45: "Immutable данные в JS приложениях", Дмитрий Кунин, MoscowJS 20

Вопросы?Дмитрий Кунин

vcard : dkun.indemo + libs : bit.ly/imm-jstwitter : DKuninSkype : dkunin1985