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.37k stars 194 forks source link

issue while working with Promise #153

Closed yavuzmester closed 7 years ago

yavuzmester commented 7 years ago
const names = [{name: "Bob"}, {name: "Foo"}];
console.log("names:" + JSON.stringify(names));

Promise.all(
    names.map(n => {
        return Promise.resolve(n).then(n => {
            console.log("n:" + JSON.stringify(n));
            return n;
        })
    })
).then(namesBack => {
    console.log("namesBack:" + JSON.stringify(namesBack));
});

The code above results in this:

names:[{"name":"Bob"},{"name":"Foo"}] n:{"name":"Bob"} n:{"name":"Foo"} namesBack:[{"name":"Bob"},{"name":"Foo"}]

However If you only change the first line to use immutable like this:

const names = Immutable.from([{name: "Bob"}, {name: "Foo"}]);
console.log("names:" + JSON.stringify(names));

Promise.all(
    names.map(n => {
        return Promise.resolve(n).then(n => {
            console.log("n:" + JSON.stringify(n));
            return n;
        })
    })
).then(namesBack => {
    console.log("namesBack:" + JSON.stringify(namesBack));
});

The result differs:

names:[{"name":"Bob"},{"name":"Foo"}] n:{"name":"Bob"} n:{"name":"Foo"} namesBack:[{"_45":0,"_81":0,"_65":null,"_54":null},{"_45":0,"_81":0,"_65":null,"_54":null}]

If we call asMutable() before .map call, then we are fine:

const names = Immutable.from([{name: "Bob"}, {name: "Foo"}]);
console.log("names:" + JSON.stringify(names));

Promise.all(
    names.asMutable().map(n => {
        return Promise.resolve(n).then(n => {
            console.log("n:" + JSON.stringify(n));
            return n;
        })
    })
).then(namesBack => {
    console.log("namesBack:" + JSON.stringify(namesBack));
});

result:

names:[{"name":"Bob"},{"name":"Foo"}] n:{"name":"Bob"} n:{"name":"Foo"} namesBack:[{"name":"Bob"},{"name":"Foo"}]

We have no intent to mutate anything, so there should not be a need to call asMutable. An enhancement to the "seamless-immutable" would be good.

Stuk commented 7 years ago

This can be simplified down to:

const promise = Immutable.from(Promise.resolve(123))
console.log(promise);
promise.then(console.log)

which results in:

{}

promise.then(console.log)
        ^
TypeError: promise.then is not a function
   ...

Promises can be considered immutable, and this library should probable treat them as such.

dhirendrarathod2000 commented 7 years ago

@rtfeldman Any ETA when the fix will be merged to master?