rtfeldman / seamless-immutable

Immutable data structures for JavaScript which are backwards-compatible with normal JS Arrays and Objects.
BSD 3-Clause "New" or "Revised" License
5.36k stars 194 forks source link

Infinite loop with promises (since 7.1.0) #217

Open mjl opened 7 years ago

mjl commented 7 years ago

I have stumbled on an infinite loop problem when dealing with promises.

I have been able to reduce the problem to the following couple of lines (copypasted from Chrome console). My angular app does an ajax request, then stores it in a redux store, something like this:

>> temp1
l {object_count: 6666, objects: Array(20), object_list_truncated: 20, seq: 1, $promise: f…}
>> i = Immutable({})
Object {merge: function, replace: function, without: function, asMutable: function, set: function…}
>> ii = i.set("result", temp1)
Object {result: Object, merge: function, replace: function, without: function, asMutable: function…}
>> ii.result <--- ** HANGS, consumes 100% cpu, must be killed in task manager **

However, if I clear out the $promise property first:

>> temp1.$promise = null
null
>> temp1
l {object_count: 41, objects: Array(20), object_list_truncated: 20, seq: 1, $promise: null…}
>> i = Immutable({})
Object {merge: function, replace: function, without: function, asMutable: function, set: function…}
>> ii = i.set("result", temp1)
Object {result: Object, merge: function, replace: function, without: function, asMutable: function…}
>> ii.result
Object {object_count: 41, objects: Array(20), object_list_truncated: 20, seq: 1, $promise: null…}

everything works fine as expected.

I guess something breaks when immutabling (is that even a word?) promises, and that leads to an infinite loop when touching the object later. Also, this is an angular $q object which might be slightly different to a stock Promise.

This seems to have appeared with 7.1.0, possibly 7.1.1, but it worked fine with 7.0.0. It might be related to pull #194 which happened in that time frame.