2019-07-24 15:20:41 -07:00
|
|
|
import constant from 'lodash/constant';
|
|
|
|
import filter from 'lodash/fp/filter';
|
|
|
|
import map from 'lodash/fp/map';
|
|
|
|
import flow from 'lodash/flow';
|
2018-07-03 15:47:15 -04:00
|
|
|
import zipObject from 'lodash/zipObject';
|
New promise helper, `resolvePromiseProperties`
`resolvePromiseProperties` takes on object and returns a promise which
resolves to a copy of the object. This copy has all its immediate
properties which were Promises replaced with the resolved value of
those promises. Promises are run with `Promise.all`. Errors are passed
up to the outer promise chain.
Example usage:
```js
resolvePromiseProperties({
promise: Promise.resolve("this property will resolve to this string"),
nonPromise: "this will remain the same",
// you can nest the function
nestedPromiseInside: resolvePromiseProperties({
nestedPromise: Promise.resolve("this will resolve"),
nestedNonPromise: "this stays the same",
}),
})
.then(obj => console.log(obj))
```
That will produce the following output:
```js
{
promise: "this property will resolve to this string",
nonPromise: "this will remain the same",
nestedPromiseInside: {
nestedPromise: "this will resolve",
nestedNonPromise: "this stays the same",
},
}
```
2017-03-17 13:56:34 -07:00
|
|
|
|
2017-03-06 16:05:08 -08:00
|
|
|
export const filterPromises = (arr, filter) =>
|
2019-07-24 15:20:41 -07:00
|
|
|
Promise.all(arr.map(entry => Promise.resolve(entry).then(filter))).then(bits =>
|
|
|
|
arr.filter(() => bits.shift()),
|
|
|
|
);
|
|
|
|
|
|
|
|
export const filterPromisesWith = filter => arr => filterPromises(arr, filter);
|
New promise helper, `resolvePromiseProperties`
`resolvePromiseProperties` takes on object and returns a promise which
resolves to a copy of the object. This copy has all its immediate
properties which were Promises replaced with the resolved value of
those promises. Promises are run with `Promise.all`. Errors are passed
up to the outer promise chain.
Example usage:
```js
resolvePromiseProperties({
promise: Promise.resolve("this property will resolve to this string"),
nonPromise: "this will remain the same",
// you can nest the function
nestedPromiseInside: resolvePromiseProperties({
nestedPromise: Promise.resolve("this will resolve"),
nestedNonPromise: "this stays the same",
}),
})
.then(obj => console.log(obj))
```
That will produce the following output:
```js
{
promise: "this property will resolve to this string",
nonPromise: "this will remain the same",
nestedPromiseInside: {
nestedPromise: "this will resolve",
nestedNonPromise: "this stays the same",
},
}
```
2017-03-17 13:56:34 -07:00
|
|
|
|
2018-08-07 14:46:54 -06:00
|
|
|
export const resolvePromiseProperties = obj => {
|
2017-04-06 16:51:01 -07:00
|
|
|
// Get the keys which represent promises
|
2018-08-07 14:46:54 -06:00
|
|
|
const promiseKeys = Object.keys(obj).filter(key => typeof obj[key].then === 'function');
|
New promise helper, `resolvePromiseProperties`
`resolvePromiseProperties` takes on object and returns a promise which
resolves to a copy of the object. This copy has all its immediate
properties which were Promises replaced with the resolved value of
those promises. Promises are run with `Promise.all`. Errors are passed
up to the outer promise chain.
Example usage:
```js
resolvePromiseProperties({
promise: Promise.resolve("this property will resolve to this string"),
nonPromise: "this will remain the same",
// you can nest the function
nestedPromiseInside: resolvePromiseProperties({
nestedPromise: Promise.resolve("this will resolve"),
nestedNonPromise: "this stays the same",
}),
})
.then(obj => console.log(obj))
```
That will produce the following output:
```js
{
promise: "this property will resolve to this string",
nonPromise: "this will remain the same",
nestedPromiseInside: {
nestedPromise: "this will resolve",
nestedNonPromise: "this stays the same",
},
}
```
2017-03-17 13:56:34 -07:00
|
|
|
|
2017-04-06 16:51:01 -07:00
|
|
|
const promises = promiseKeys.map(key => obj[key]);
|
New promise helper, `resolvePromiseProperties`
`resolvePromiseProperties` takes on object and returns a promise which
resolves to a copy of the object. This copy has all its immediate
properties which were Promises replaced with the resolved value of
those promises. Promises are run with `Promise.all`. Errors are passed
up to the outer promise chain.
Example usage:
```js
resolvePromiseProperties({
promise: Promise.resolve("this property will resolve to this string"),
nonPromise: "this will remain the same",
// you can nest the function
nestedPromiseInside: resolvePromiseProperties({
nestedPromise: Promise.resolve("this will resolve"),
nestedNonPromise: "this stays the same",
}),
})
.then(obj => console.log(obj))
```
That will produce the following output:
```js
{
promise: "this property will resolve to this string",
nonPromise: "this will remain the same",
nestedPromiseInside: {
nestedPromise: "this will resolve",
nestedNonPromise: "this stays the same",
},
}
```
2017-03-17 13:56:34 -07:00
|
|
|
|
2017-04-06 16:51:01 -07:00
|
|
|
// Resolve all promises
|
2018-08-07 14:46:54 -06:00
|
|
|
return Promise.all(promises).then(resolvedPromises =>
|
2017-04-06 16:51:01 -07:00
|
|
|
// Return a copy of obj with promises overwritten by their
|
|
|
|
// resolved values
|
2018-08-07 14:46:54 -06:00
|
|
|
Object.assign({}, obj, zipObject(promiseKeys, resolvedPromises)),
|
|
|
|
);
|
2017-04-06 16:51:01 -07:00
|
|
|
};
|
2018-06-11 19:03:43 -07:00
|
|
|
|
|
|
|
export const then = fn => p => Promise.resolve(p).then(fn);
|
2019-07-24 15:20:41 -07:00
|
|
|
|
|
|
|
const filterPromiseSymbol = Symbol('filterPromiseSymbol');
|
|
|
|
export const onlySuccessfulPromises = flow([
|
|
|
|
then(map(p => p.catch(constant(filterPromiseSymbol)))),
|
|
|
|
then(Promise.all.bind(Promise)),
|
|
|
|
then(filter(maybeValue => maybeValue !== filterPromiseSymbol)),
|
|
|
|
]);
|
2019-11-26 09:40:27 +01:00
|
|
|
|
|
|
|
const wrapFlowAsync = fn => async arg => fn(await arg);
|
|
|
|
export const flowAsync = fns => flow(fns.map(fn => wrapFlowAsync(fn)));
|