So my thinking was right, when recursing with promises, we end up calling all chained callbacks for however many times we recurse, for example
function p() {
return new Promise(function (r) {
process.nextTick(r);
})
}
function recurse(count) {
return p().then(function () {
if (count < 10) {
console.log('count => ', count);
return recurse(++count);
}
}).then(function(){
console.log('a');
return 5;
});
}
recurse(1).then(function () {
console.log('done');
});
If you run the above, we get:
count => 1
count => 2
count => 3
count => 4
count => 5
count => 6
count => 7
count => 8
count => 9
a
a
a
a
a
a
a
a
a
a
done
Is there a way to register this callback with console.log('a') just once instead of registering it 10 times?
I don't think I want/need this function to be called 10 times, and would like to find a way to have it called just once.
I am actually just as interested in a similar solution for Observables, specifically RxJS5 Observables.
If the recursion is synchronous, you can simply recurse within the .then
's function
new Promise(res => {
res(); // dummy initial promise
}).then(() => {
function recurse(x) { // recursion inside then
console.log('x', x);
if (x < 10) return recurse(++x);
return x;
}
return recurse(1); // begin recursion
}).then(y => { // this only fires once recursion above is resolved
console.log('y', y);
return 5;
}).then(z => console.log('z', z));
// x 1
// ... (synchronous)
// x 10
// y 10 (value passed from resolving inner promise)
// z 5 (value returned from previous then)
Or if our recursive function is asynchronous, we can have it return a promise too, so you end up with a recursion which looks like this
function doWork() {
function addOne(x) {
return new Promise((res, rej) => {
// async bit here
res(x + 1);
});
}
function recurse(x) {
if (x < 10) return addOne(x).then(recurse);
return x;
}
return recurse(1);
}
And in a promise chain, would look like this
new Promise(res => {
res(); // dummy initial promise
}).then(() => {
return doWork();
}).then(y => {
console.log(y);
});