Skip to main content
add one more solution
Source Link
hakobpogh
  • 677
  • 6
  • 13

if you want to keep itThere are some solutions for your issue with microtasks then you can do the followingusing native tasks. this one is using Promise to schedule a microtask:

(function() { function sum(arr, i = 0) { if(arr.length === i) { return Promise.resolve(0); } return Promise.resolve(null) .then(() => sum(arr, i + 1)) .then((x) => x + arr[i]); } sum(a).then(s => console.log(s)); }()); 

but this will force be the engine to wait until the execution is completed. So for huge arrays, I wouldn't recommend you doing this on the main thread.

You can also do the following:

(function() { function sum(arr, i = 0) { if(arr.length === i) { return Promise.resolve(0); } return new Promise(resolve => { setTimeout(() => { sum(arr, i + 1).then(x => resolve(x + arr[i])); }); }); } sum(a).then(s => console.log(s)); }()); 

then with makingmake a few changes to this code and making it more elegant, we can do the following:

(function() { const defer = () => new Promise((resolve) => setTimeout(resolve)); async function sum(arr, i = 0) { if(arr.length === i) { return 0 } await defer(); return await sum(arr, i + 1) + arr[i]; } sum(a).then(s => console.log(s)); }()); 

and if your environment supports tail recursion you can change this to use it: http://2ality.com/2015/06/tail-call-optimization.html

UPDATE

actually, there is one more way to do this. rxjs library provides a queue scheduler which can help you make a recursive logic to be iterative without making many changes in your code. I've created an example of your sum method here.

if you want to keep it with microtasks then you can do the following:

(function() { function sum(arr, i = 0) { if(arr.length === i) { return Promise.resolve(0); } return Promise.resolve(null) .then(() => sum(arr, i + 1)) .then((x) => x + arr[i]); } sum(a).then(s => console.log(s)); }()); 

but this will force be the engine to wait until the execution is completed. So for huge arrays, I wouldn't recommend you doing this.

You can also do the following:

(function() { function sum(arr, i = 0) { if(arr.length === i) { return Promise.resolve(0); } return new Promise(resolve => { setTimeout(() => { sum(arr, i + 1).then(x => resolve(x + arr[i])); }); }); } sum(a).then(s => console.log(s)); }()); 

then with making few changes to this code and making it more elegant, we can do the following:

(function() { const defer = () => new Promise((resolve) => setTimeout(resolve)); async function sum(arr, i = 0) { if(arr.length === i) { return 0 } await defer(); return await sum(arr, i + 1) + arr[i]; } sum(a).then(s => console.log(s)); }()); 

and if your environment supports tail recursion you can change this to use it: http://2ality.com/2015/06/tail-call-optimization.html

There are some solutions for your issue with using native tasks. this one is using Promise to schedule a microtask:

(function() { function sum(arr, i = 0) { if(arr.length === i) { return Promise.resolve(0); } return Promise.resolve(null) .then(() => sum(arr, i + 1)) .then((x) => x + arr[i]); } sum(a).then(s => console.log(s)); }()); 

but this will force the engine to wait until the execution is completed. So for huge arrays, I wouldn't recommend you doing this on the main thread.

You can also do the following:

(function() { function sum(arr, i = 0) { if(arr.length === i) { return Promise.resolve(0); } return new Promise(resolve => { setTimeout(() => { sum(arr, i + 1).then(x => resolve(x + arr[i])); }); }); } sum(a).then(s => console.log(s)); }()); 

then with make a few changes to this code and making it more elegant, we can do the following:

(function() { const defer = () => new Promise((resolve) => setTimeout(resolve)); async function sum(arr, i = 0) { if(arr.length === i) { return 0 } await defer(); return await sum(arr, i + 1) + arr[i]; } sum(a).then(s => console.log(s)); }()); 

and if your environment supports tail recursion you can change this to use it: http://2ality.com/2015/06/tail-call-optimization.html

UPDATE

actually, there is one more way to do this. rxjs library provides a queue scheduler which can help you make a recursive logic to be iterative without making many changes in your code. I've created an example of your sum method here.

Source Link
hakobpogh
  • 677
  • 6
  • 13

if you want to keep it with microtasks then you can do the following:

(function() { function sum(arr, i = 0) { if(arr.length === i) { return Promise.resolve(0); } return Promise.resolve(null) .then(() => sum(arr, i + 1)) .then((x) => x + arr[i]); } sum(a).then(s => console.log(s)); }()); 

but this will force be the engine to wait until the execution is completed. So for huge arrays, I wouldn't recommend you doing this.

You can also do the following:

(function() { function sum(arr, i = 0) { if(arr.length === i) { return Promise.resolve(0); } return new Promise(resolve => { setTimeout(() => { sum(arr, i + 1).then(x => resolve(x + arr[i])); }); }); } sum(a).then(s => console.log(s)); }()); 

then with making few changes to this code and making it more elegant, we can do the following:

(function() { const defer = () => new Promise((resolve) => setTimeout(resolve)); async function sum(arr, i = 0) { if(arr.length === i) { return 0 } await defer(); return await sum(arr, i + 1) + arr[i]; } sum(a).then(s => console.log(s)); }()); 

and if your environment supports tail recursion you can change this to use it: http://2ality.com/2015/06/tail-call-optimization.html