I want to return objects with a custom shape from promise.allSettled
let fns = [
{ fn: fn1, name: "myName1" },
{ fn: fn2, name: "myName2" },
];
const allData = await Promise.allSettled(
fns.map((entry) =>
entry.fn
.then((res) => ({
name: entry.name,
status: "fulfilled",
res: res.Data,
}))
.catch((err) => ({
name: entry.name,
status: "rejected",
res: undefined,
}))
)
);
upon looping over this list, I only have status
and reason
available. Is it possible to return custom objects like this?
CodePudding user response:
This was mentioned in the comments above but I'll elaborate...
Promise.allSettled()
is used to resolve a list of promises, whether they succeed or fail. It provides you a list of results shaped either like
export interface PromiseResolution<T> { status: 'fulfilled'; value: T; }
or
export interface PromiseRejection<E> { status: 'rejected'; reason: E; }
Since you are manually handling rejection, all your promises resolve successfully so you don't need the features that allSettled()
offers.
Instead, simply use Promise.all()
.
const allData = await Promise.all(
fns.map(({ fn, name }) =>
fn
.then(({ Data }) => ({
name,
status: "fulfilled",
res: Data,
}))
.catch(() => ({
name,
status: "rejected",
}))
)
);
Also, if fn1
and fn2
are promises, they're poorly named. If they're functions, you should be calling them.
CodePudding user response:
I think your code is some kind of strange.
When you track the code:
Promise.allSettled()
takes an array generated from themap
method- The array generated from the
map
method in fact contains objects and not promises, and that's because you resolve the promises already in thatmap
method, so the values inside the array passed toPromise.allSettled()
are just objects. - And when the
Promise.allSettled()
takes inside its array any value that's not a promise, it consider that value as a resolved promise already and will put that value in the array of results that you can get in the.then()
handler. - So the results array will contains its normal objects with a resolved promises each value will be the object passed to it, and all status is
fulfilled
So, you can imagine that your Promise.allSettled()
takes an array like that:
let allData = Promise.allSettled([
{ name: "myName1", status: "fulfilled", res: "" },
{ name: "myName2", status: "fulfilled", res: "" }
])
So, it will consider the two objects as a resolved promises, then if you handle that promise like that:
allData.then((results) => {
console.log( results )
})
You will find this result:
[
{status: "fulfilled", value: { name: "myName1", status: "fulfilled", res: "" }},
{status: "fulfilled", value: { name: "myName2", status: "fulfilled", res: "" }}
]
Now I think it's clear to you, what your code is ready does.
Let's come to the main question,
Can I handle the object returned in the array of result in the
Promise.allSettled()
And the answer is No
for sorry, because this is something in the builtin structure of Promise.allSettled()
that it works with.
But you can structure the object in the value of the object that returned by the Promise.allSettled()
I hope I helped you understand that.