Reputation: 3535
I run into this every now and then:
return somethingThatReturnsAPromise()
.then((response) => {
soSomethingg(); // Eg; update the UI
return response;
});
Now I'm looking for something that is not expected to return anything and won't change the promise chain if I forget that:
return somethingThatReturnsAPromise()
.whatImLookingFor((response) => {
doSomething(); // Eg; update the UI
})
.then((response) => {
// and this one should still be able to access response
});
Maybe this goes against the idea of promises, but for me, it's a bit inconvenient since I can't pass arbitrary functions.
One idea is to compose a function:
const sideEffect = (callback) => {
return (response) => {
callback(response);
return response;
};
};
And I could use it as
return somethingThatReturnsAPromise()
.then(sideEffect(doSomething));
But I'd prefer something instead of then
is there something like that?
Note: I'm working with Angular 1.x so I need something like for that.
Upvotes: 2
Views: 63
Reputation: 522250
I would assume that you're not really writing .then().then()
, because you could collapse that into a single .then
, but that your concern is really about returning the promise and having some external code add another then
to the chain. In that case do this:
let p = somethingThatReturnsAPromise();
p.then(() => doSomething());
return p;
This allows the caller to attach additional then
s to the original promise instead of chaining off of your .then
, thereby receiving the original promise's value. This is called branching the promise chain.
Upvotes: 2
Reputation: 1074676
Maybe this goes against the idea of promises
Slightly, promise chains are pipelines where then
handlers transform things at each stage. But it's perfectly valid to want to pass through the value unchanged.
One idea is to compose a function:
Indeed the first thing that came to mind, and how I'd do it.
But I'd prefer something instead of
then
is there something like that?
There isn't. You could add it for your own projects (I wouldn't in a library) by adding it to Promise.prototype
. Or you could give yourselve a Promise
subclass and add it there.
With a Promise sublass you'd do something like:
return MyPromise.resolve(somethingThatReturnsAPromise())
.thenSide(soSomethingg); // Eg; update the UI
...where thenSide
is your method that's then
but passing the original value back unchanged, e.g.:
class MyPromise extends Promise {
thenSide(callback) {
this.then(callback);
return this;
}
}
or
class MyPromise extends Promise {
thenSide(callback) {
this.then(callback);
return MyPromise.resolve(this);
}
}
...depending on whether you're bothered about thenSide
returning the same promise (since then
always returns a new one).
Upvotes: 2
Reputation: 1948
As far as I know (I could well be wrong) the wrapper method for "pass-through" side-effects is an idiomatic way to do what you want.
Alternatively (if you need the same response
in multiple places) you can break up the promise chain when you encounter a situation like this.
Upvotes: 0