Browse Source

[Promise.object] initial implementation

* Resolves normal objects
* Resolves promises in objects
* Resolves nested promises
* Fails on circular objects with more than one ref to self
tags/v0.10.0
Muthu Kumar 7 years ago
parent
commit
28d0b8e13a
  1. 67
      index.js

67
index.js

@ -0,0 +1,67 @@
"use strict";
const isObject = obj => obj && typeof obj === 'object' && obj.constructor === Object;
const makeCircular = (obj, path) => {
const start = (o, p, i = 1) => {
if (i === path.length) return o[p[0]] = obj;
if (p.length > 0) {
o[p[0]] = {};
return start(o[p[0]], p.slice(1), i + 1);
} else return obj;
}
return start(obj, path);
};
const findPath = (obj, query) => {
return Object.keys(obj).reduce((acc, key) => {
const value = obj[key];
if (value === query) return [...acc, key];
if (isObject(value)) return [...acc, ...findPath(value)];
else return acc;
}, []);
};
// Resolves array
const PromiseMap = (arr, functor) =>
Promise.all(arr.map(x => Promise.resolve(x).then(functor)));
// Resolves objects
const ResolveObject = obj =>
Promise.all(
Object.keys(obj).map(key =>
Promise.resolve(obj[key]).then(val => obj[key] = val))
)
.then(_ => obj);
// Resolves recrusive deep objects
const PromiseObject = parent => {
const ResolveDeepObject = object =>
Promise
.resolve(object)
.then(obj => {
if (Array.isArray(obj)) {
return PromiseMap(obj, obj => ResolveDeepObject(obj));
} else if (isObject(obj)) {
return ResolveObject(
Object
.keys(obj)
.reduce((acc, key) =>
(obj[key] === parent) ? {
...acc,
[key]: '[[ SELF ]]',
} : {
...acc,
[key]: ResolveDeepObject(obj[key]),
}, {}));
}
return obj;
});
return ResolveDeepObject(parent)
.then(obj => {
const path = findPath(obj, '[[ SELF ]]');
return path.length > 0 ? makeCircular(obj, path) : obj;
})
};
module.exports = PromiseObject;
Loading…
Cancel
Save