3

The code goes like this:

function test(value){
  return new Promise(function (fulfill, reject){
     try {
       fulfill(true);
     } catch(e) {
       throw e;
     }
  });
}

My concern is, when you use Promise and throw error instead of reject(e), will this cause a memory leak?

Because for me, throwing an error instead of rejecting it will not reject or exit the error outside promise. The error will just go around inside the Promise. Let me know your opinion.

Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
happy go lucky
  • 361
  • 3
  • 13

2 Answers2

4

Throwing an error will automatically reject the Promise. Read more about it here

But there is something to discuss about. Look at the following code. The code throw an error.the error is thrown from the inside of a promise. It will automatically rejected and initiate the catch chain.

function test(value){
  return new Promise(function (fulfill, reject){

       throw e;

  });
}

test('sample text').then(result=>console.log(result)).catch(result=>console.log(result))

But what if I've used a Web API e.g setTimeout() inside my promise. Look at the following code:

function test(value){
  return new Promise(function (fulfill, reject){
       setTimeout(function(){
          throw new Error('haha');
       },1000)


  });
}

test('sample text').then(result=>console.log(result)).catch(result=>console.log(result))

Web APIs are asynchronous. Whenever a Web API is called from inside a promise, the JavaScript engine take that async code outside for execution. In simpler words, web APIs or asynchronous code gets executed outside of the main call stack.

So, throwing an error from setTimeout() won't have any reference of the caller promise, thus can't initiate the catch block. You need to reject() it from setTimeout() to initiate the catch block if there is any error.

Will it cause a memory leak?

Answer: no

the test().then().catch() will be garbage collected as soon as it finished executing. But if you would've kept the promise in a global variable like var p = test(); p.then().catch() then the variable p will stay in memory, it won't be garbage collected. But that's not a memory leak. Memory leak is a completely different aspect and doesn't apply in this kind of scenario.

Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
AL-zami
  • 8,902
  • 15
  • 71
  • 130
  • 1
    It will, but it's also irrelevant for a memory leak. A promise is just a Javascript object and will be garbage collected when nobody retains a reference to it, whether it's resolved, rejected or still pending. – jfriend00 Jan 26 '18 at 02:55
  • @jfriend00 - it will cause memory leak if there are lots of pending and rejected processes that needs to be garbage collected right? So if those processes are bumping up, those will create leaks since it consumes memory. Correct? – happy go lucky Jan 26 '18 at 03:19
  • 1
    @happygolucky - No. An object that will be garbage collected is not a leak. A leak is something that will never be garbage collected. Leaks by definition are something that accumulate and are not cleaned up by the system. If you're in a tight loop making millions of objects that need to be garbage collected that might create a temporary memory problem, but that's not a leak or an issue caused by what this question is about. – jfriend00 Jan 26 '18 at 04:24
1

This will not cause a memory leak. However, there are differences worth to consider when using one or the other.

  • Unlike throw, reject() will not terminate the control flow. So, if you have code that you want to continue executing after a rejection, you will probably prefer reject().

  • Using throw in nested promises can cause unexpected results. In such cases, it is recommended to use reject().

Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
Julian
  • 146
  • 1
  • 3
  • 1
    Could you elaborate on `Using throw in nested promises can cause unexpected results`? Providing some references on this subject is appreciated. – Alexander Abakumov Oct 04 '18 at 15:02