Resolve Javascript Promise outside function scope











up vote
174
down vote

favorite
40












I have been using ES6 Promise.



Ordinarily, a Promise is constructed and used like this



new Promise(function(resolve, reject){
if (someCondition){
resolve();
} else {
reject();
}
});


But I have been doing something like below to take the resolve outside for the sake of flexibility.



var outsideResolve;
var outsideReject;
new Promise(function(resolve, reject) {
outsideResolve = resolve;
outsideReject = reject;
});


And later



onClick = function(){
outsideResolve();
}


This works fine, but is there an easier way to do this? If not, is this a good practice?










share|improve this question




















  • 1




    I don't think there is another way. I believe it is specified that the callback passed to Promise has to be executed synchronously to allow "exporting" the two functions.
    – Felix Kling
    Oct 1 '14 at 20:44








  • 1




    This works for me exactly like you wrote it. So as far as I'm concerned, this is the "canonical" way.
    – Gilad Barner
    Jul 31 '16 at 8:40






  • 1




    I think there should be a formal way to achieve this in the future. This feature is very powerful in my opinion as you can wait for values from other contexts.
    – Jose Nunez
    Apr 3 at 12:47










  • Whenever they come up with a proper solution to this problem, I hope they will also make it work for nested promises, some of which may recur.
    – Arthur Tarasov
    Jul 5 at 8:02















up vote
174
down vote

favorite
40












I have been using ES6 Promise.



Ordinarily, a Promise is constructed and used like this



new Promise(function(resolve, reject){
if (someCondition){
resolve();
} else {
reject();
}
});


But I have been doing something like below to take the resolve outside for the sake of flexibility.



var outsideResolve;
var outsideReject;
new Promise(function(resolve, reject) {
outsideResolve = resolve;
outsideReject = reject;
});


And later



onClick = function(){
outsideResolve();
}


This works fine, but is there an easier way to do this? If not, is this a good practice?










share|improve this question




















  • 1




    I don't think there is another way. I believe it is specified that the callback passed to Promise has to be executed synchronously to allow "exporting" the two functions.
    – Felix Kling
    Oct 1 '14 at 20:44








  • 1




    This works for me exactly like you wrote it. So as far as I'm concerned, this is the "canonical" way.
    – Gilad Barner
    Jul 31 '16 at 8:40






  • 1




    I think there should be a formal way to achieve this in the future. This feature is very powerful in my opinion as you can wait for values from other contexts.
    – Jose Nunez
    Apr 3 at 12:47










  • Whenever they come up with a proper solution to this problem, I hope they will also make it work for nested promises, some of which may recur.
    – Arthur Tarasov
    Jul 5 at 8:02













up vote
174
down vote

favorite
40









up vote
174
down vote

favorite
40






40





I have been using ES6 Promise.



Ordinarily, a Promise is constructed and used like this



new Promise(function(resolve, reject){
if (someCondition){
resolve();
} else {
reject();
}
});


But I have been doing something like below to take the resolve outside for the sake of flexibility.



var outsideResolve;
var outsideReject;
new Promise(function(resolve, reject) {
outsideResolve = resolve;
outsideReject = reject;
});


And later



onClick = function(){
outsideResolve();
}


This works fine, but is there an easier way to do this? If not, is this a good practice?










share|improve this question















I have been using ES6 Promise.



Ordinarily, a Promise is constructed and used like this



new Promise(function(resolve, reject){
if (someCondition){
resolve();
} else {
reject();
}
});


But I have been doing something like below to take the resolve outside for the sake of flexibility.



var outsideResolve;
var outsideReject;
new Promise(function(resolve, reject) {
outsideResolve = resolve;
outsideReject = reject;
});


And later



onClick = function(){
outsideResolve();
}


This works fine, but is there an easier way to do this? If not, is this a good practice?







javascript promise es6-promise






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jun 29 '17 at 19:13

























asked Oct 1 '14 at 20:40









Morio

2,13131625




2,13131625








  • 1




    I don't think there is another way. I believe it is specified that the callback passed to Promise has to be executed synchronously to allow "exporting" the two functions.
    – Felix Kling
    Oct 1 '14 at 20:44








  • 1




    This works for me exactly like you wrote it. So as far as I'm concerned, this is the "canonical" way.
    – Gilad Barner
    Jul 31 '16 at 8:40






  • 1




    I think there should be a formal way to achieve this in the future. This feature is very powerful in my opinion as you can wait for values from other contexts.
    – Jose Nunez
    Apr 3 at 12:47










  • Whenever they come up with a proper solution to this problem, I hope they will also make it work for nested promises, some of which may recur.
    – Arthur Tarasov
    Jul 5 at 8:02














  • 1




    I don't think there is another way. I believe it is specified that the callback passed to Promise has to be executed synchronously to allow "exporting" the two functions.
    – Felix Kling
    Oct 1 '14 at 20:44








  • 1




    This works for me exactly like you wrote it. So as far as I'm concerned, this is the "canonical" way.
    – Gilad Barner
    Jul 31 '16 at 8:40






  • 1




    I think there should be a formal way to achieve this in the future. This feature is very powerful in my opinion as you can wait for values from other contexts.
    – Jose Nunez
    Apr 3 at 12:47










  • Whenever they come up with a proper solution to this problem, I hope they will also make it work for nested promises, some of which may recur.
    – Arthur Tarasov
    Jul 5 at 8:02








1




1




I don't think there is another way. I believe it is specified that the callback passed to Promise has to be executed synchronously to allow "exporting" the two functions.
– Felix Kling
Oct 1 '14 at 20:44






I don't think there is another way. I believe it is specified that the callback passed to Promise has to be executed synchronously to allow "exporting" the two functions.
– Felix Kling
Oct 1 '14 at 20:44






1




1




This works for me exactly like you wrote it. So as far as I'm concerned, this is the "canonical" way.
– Gilad Barner
Jul 31 '16 at 8:40




This works for me exactly like you wrote it. So as far as I'm concerned, this is the "canonical" way.
– Gilad Barner
Jul 31 '16 at 8:40




1




1




I think there should be a formal way to achieve this in the future. This feature is very powerful in my opinion as you can wait for values from other contexts.
– Jose Nunez
Apr 3 at 12:47




I think there should be a formal way to achieve this in the future. This feature is very powerful in my opinion as you can wait for values from other contexts.
– Jose Nunez
Apr 3 at 12:47












Whenever they come up with a proper solution to this problem, I hope they will also make it work for nested promises, some of which may recur.
– Arthur Tarasov
Jul 5 at 8:02




Whenever they come up with a proper solution to this problem, I hope they will also make it work for nested promises, some of which may recur.
– Arthur Tarasov
Jul 5 at 8:02












9 Answers
9






active

oldest

votes

















up vote
53
down vote



accepted










No, there is no other way to do this - the only thing I can say is that this use case isn't very common. Like Felix said in the comment - what you do will consistently work.



It's worth mentioning that the reason the promise constructor behaves this way is throw safety - if an exception you did not anticipate happens while your code is running inside the promise constructor it will turn into a rejection, this form of throw safety - converting thrown errors to rejections is important and helps maintain predictable code.



For this throw safety reason, the promise constructor was chosen over deferreds (which are an alternative promise construction way that do allow what you're doing) - as for best practices - I'd pass the element and use the promise constructor instead:



var p = new Promise(function(resolve, reject){
this.onclick = resolve;
}.bind(this));


For this reason - whenever you can use the promise constructor over exporting the functions - I recommend you do use it. Whenever you can avoid both - avoid both and chain.



Note, that you should never use the promise constructor for things like if(condition), the first example could be written as:



var p = Promise[(someCondition)?"resolve":"reject"]();





share|improve this answer

















  • 1




    Hi Benjamin! Is there currently no better way of getting yummy promise sugar if we don't know when the promise will be fulfilled yet? Like some sort of asynchronous wait/notify pattern? Like for example, "store", and later invoke a Promise chain? E.g. in my particular case, I am on a server, waiting for a specific client reply (a SYN-ACK-kinda hand-shake to make sure the client successfully updated state).
    – Domi
    May 3 '15 at 13:17








  • 1




    @Domi check out q-connection and RxJS.
    – Benjamin Gruenbaum
    May 3 '15 at 14:09










  • Hah, as usual, I was too impatient to wait! Either way, it seems like what those libraries are doing is overkill for my particular use-case, unless they are fixing issues that I have overlooked. Mind taking a look at my minimal solution?
    – Domi
    May 3 '15 at 14:17








  • 1




    How could do I the same using fetch API?
    – Vinod Sobale
    Apr 20 '17 at 5:05






  • 24




    Not common? I end up needing it almost every project.
    – Tomáš Zato
    Jun 23 '17 at 15:24


















up vote
80
down vote













simple:



var promiseResolve, promiseReject;

var promise = new Promise(function(resolve, reject){
promiseResolve = resolve;
promiseReject = reject;
});

promiseResolve();





share|improve this answer

















  • 1




    @ruX, As the accepted answer mentions - it was designed this way on purpose. The point is that if an exception is thrown it will be caught by the promise constructor. This answer (as well as mine) has the pitfall of possibly throwing an exception for whatever code calls promiseResolve(). The semantics of a promise are that it always returns a value. Also this is functionally the same as OP's post, I don't get what problem this is solving in a reusable way.
    – Jon Jaques
    Jun 27 '16 at 20:30








  • 2




    @JonJaques I'm not sure if what you say is true. The code that calls promiseResolve() will not throw an exception. You can define a .catch on the constructor and no matter what code calls it, the constructor's .catch will be called. Here is the jsbin demonstrating how this works: jsbin.com/yicerewivo/edit?js,console
    – carter
    Jul 5 '16 at 22:26










  • Yeah, it's caught because you wrapped another promise constructor around it - Exactly the point I'm trying to make. However, lets say you have some other code that's trying to call resolve() outside of the constructor (aka Deferred object)... It could throw an exception and not be caught jsbin.com/cokiqiwapo/1/edit?js,console
    – Jon Jaques
    Jul 6 '16 at 13:26










  • I see what you mean now, but I don't see how that relates to creating flexible promise resolvers. If you throw an error outside of something that can catch it, then it doesn't get caught. This is not a pitfall of a promise pattern. This is just an example of a bad pattern.
    – carter
    Jul 12 '16 at 17:17






  • 4




    I am not even sure it is a bad design. An error thrown outside the promise isn't supposed to be caught within the promise. It is perhaps an example of misconception or bad understanding, if the designer actually expects the error to be caught within.
    – KalEl
    May 11 '17 at 22:17


















up vote
61
down vote













Bit late to the party here, but another way to do it would be to use a Deferred object. You essentially have the same amount of boilerplate, but it's handy if you want to pass them around and possibly resolve outside of their definition.



Naive Implementation:



class Deferred {
constructor() {
this.promise = new Promise((resolve, reject)=> {
this.reject = reject
this.resolve = resolve
})
}
}

function asyncAction() {
var dfd = new Deferred()

setTimeout(()=> {
dfd.resolve(42)
}, 500)

return dfd.promise
}

asyncAction().then(result => {
console.log(result) // 42
})


ES5 Version:



function Deferred() {
var self = this;
this.promise = new Promise(function(resolve, reject) {
self.reject = reject
self.resolve = resolve
})
}

function asyncAction() {
var dfd = new Deferred()

setTimeout(function() {
dfd.resolve(42)
}, 500)

return dfd.promise
}

asyncAction().then(function(result) {
console.log(result) // 42
})





share|improve this answer



















  • 1




    Do notice the lexical scoping here.
    – Florrie
    Feb 2 '16 at 20:45










  • There is no practical difference in whether resolve|reject are assigned lexically or through bind. This is just a simple implementation of the jQuery Deferred object that has been around since 1.0(ish). It works exactly like a promise, except there is no throw safety. The whole point of this question was how to save a few lines of code when creating promises.
    – Jon Jaques
    Jul 13 '16 at 0:08










  • Using a deferred is the usual way to do this, I have no idea why this isn't higher
    – BlueRaja - Danny Pflughoeft
    Feb 28 '17 at 22:21












  • Excellent answer! Was looking for the deferred functionality that jQuery offers.
    – Anshul Koka
    Mar 28 '17 at 22:16






  • 1




    Is Deferred deprecated?
    – Pacerier
    Oct 16 '17 at 1:34


















up vote
12
down vote













A solution I came up with in 2015 for my framework. I called this type of promises Task



function createPromise(handler){
var _resolve, _reject;

var promise = new Promise(function(resolve, reject){
_resolve = resolve;
_reject = reject;

handler(resolve, reject);
})

promise.resolve = _resolve;
promise.reject = _reject;

return promise;
}

var promise = createPromise()
promise.then(function(data){ alert(data) })

promise.resolve(200) // resolve from outside





share|improve this answer






























    up vote
    7
    down vote













    I liked @JonJaques answer but I wanted to take it a step further.



    If you bind then and catch then the Deferred object, then it fully implements the Promise API and you can treat it as promise and await it and such.






    class DeferredPromise {
    constructor() {
    this._promise = new Promise((resolve, reject) => {
    // assign the resolve and reject functions to `this`
    // making them usable on the class instance
    this.resolve = resolve;
    this.reject = reject;
    });
    // bind `then` and `catch` to implement the same interface as Promise
    this.then = this._promise.then.bind(this._promise);
    this.catch = this._promise.catch.bind(this._promise);
    this[Symbol.toStringTag] = 'Promise';
    }
    }

    const deferred = new DeferredPromise();
    console.log('waiting 2 seconds...');
    setTimeout(() => {
    deferred.resolve('whoa!');
    }, 2000);

    async function someAsyncFunction() {
    const value = await deferred;
    console.log(value);
    }

    someAsyncFunction();








    share|improve this answer




























      up vote
      5
      down vote













      A helper method would alleviate this extra overhead, and give you the same jQuery feel.



      function Deferred() {
      let resolve;
      let reject;
      const promise = new Promise((res, rej) => {
      resolve = res;
      reject = rej;
      });
      return { promise, resolve, reject };
      }


      Usage would be



      const { promise, resolve, reject } = Deferred();
      displayConfirmationDialog({
      confirm: resolve,
      cancel: reject
      });
      return promise;


      Which is similar to jQuery



      const dfd = $.Deferred();
      displayConfirmationDialog({
      confirm: dfd.resolve,
      cancel: dfd.reject
      });
      return dfd.promise();




      Although, in a use case this simple, native syntax is fine



      return new Promise((resolve, reject) => {
      displayConfirmationDialog({
      confirm: resolve,
      cancel: reject
      });
      });





      share|improve this answer






























        up vote
        2
        down vote













        Our solution was to use closures to store the resolve/reject functions and additionally attach a function to extend the promise itself.



        Here is the pattern:



        function getPromise() {

        var _resolve, _reject;

        var promise = new Promise((resolve, reject) => {
        _reject = reject;
        _resolve = resolve;
        });

        promise.resolve_ex = (value) => {
        _resolve(value);
        };

        promise.reject_ex = (value) => {
        _reject(value);
        };

        return promise;
        }


        And using it:



        var promise = getPromise();

        promise.then(value => {
        console.info('The promise has been fulfilled: ' + value);
        });

        promise.resolve_ex('hello');
        // or the reject version
        //promise.reject_ex('goodbye');





        share|improve this answer



















        • 2




          Great... I'm just learning Promises but have been consistently puzzled by the fact that you don't appear to be able to resolve them "somewhere else". Using a closure to hide implementation details is a great idea... but in fact I'm not sure that's what you've done: rather than have "pseudo" private variables I'm pretty sure there's a way to completely conceal the variables which should be inaccessible... which is really what closures mean...
          – mike rodent
          Jul 3 '17 at 18:05










        • > A closure is a block of code that can be referenced (and passed around) with access to the variables of the enclosing scope. var _resolve, _reject; are the enclosing scope.
          – Steven Spungin
          Jul 3 '17 at 20:12












        • yep, fair enough. Actually it seems to me that my answer is overcomplicating things, and furthermore that your answer can be simplified: you just need to go promise.resolve_ex = _resolve; promise.reject_ex = _reject; ... still works fine.
          – mike rodent
          Jul 3 '17 at 21:03










        • "attach a function to extend the promise itself." - don't do that. Promises are result values, they should not provide the capability to resolve them. You don't want to pass those extended ones around.
          – Bergi
          Jul 4 '17 at 16:41








        • 2




          The question was how to resolve it outside of the scope. Here is a solution that works, and in our production we have actually had a necessary reason to do it. I don't see why solving the problem stated deserves a downvote.
          – Steven Spungin
          Jul 4 '17 at 20:46


















        up vote
        0
        down vote













        I wrote a small lib for this. https://www.npmjs.com/package/@inf3rno/promise.exposed



        I used the factory method approach others wrote, but I overrode the then, catch, finally methods too, so you can resolve the original promise by those as well.



        Resolving Promise without executor from outside:



        const promise = Promise.exposed().then(console.log);
        promise.resolve("This should show up in the console.");


        Racing with the executor's setTimeout from outside:



        const promise = Promise.exposed(function (resolve, reject){
        setTimeout(function (){
        resolve("I almost fell asleep.")
        }, 100000);
        }).then(console.log);

        setTimeout(function (){
        promise.resolve("I don't want to wait that much.");
        }, 100);


        There is a no-conflict mode if you don't want to pollute the global namespace:



        const createExposedPromise = require("@inf3rno/promise.exposed/noConflict");
        const promise = createExposedPromise().then(console.log);
        promise.resolve("This should show up in the console.");





        share|improve this answer




























          up vote
          0
          down vote













          I'm using a helper function to create what I call a "flat promise" -



          function flatPromise() {

          let resolve, reject;

          const promise = new Promise((res, rej) => {
          resolve = res;
          reject = rej;
          });

          return { promise, resolve, reject };
          }


          And I'm using it like so -



          function doSomethingAsync() {

          // Get your promise and callbacks
          const { resolve, reject, promise } = flatPromise();

          // Do something amazing...
          setTimeout(() => {
          resolve('done!');
          }, 500);

          // Pass your promise to the world
          return promise;

          }


          See full working example -






          function flatPromise() {

          let resolve, reject;

          const promise = new Promise((res, rej) => {
          resolve = res;
          reject = rej;
          });

          return { promise, resolve, reject };
          }

          function doSomethingAsync() {

          // Get your promise and callbacks
          const { resolve, reject, promise } = flatPromise();

          // Do something amazing...
          setTimeout(() => {
          resolve('done!');
          }, 500);

          // Pass your promise to the world
          return promise;
          }

          (async function run() {

          const result = await doSomethingAsync()
          .catch(err => console.error('rejected with', err));
          console.log(result);

          })();





          Edit:
          I have created an NPM package called flat-promise and the code is also available on GitHub.






          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














             

            draft saved


            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f26150232%2fresolve-javascript-promise-outside-function-scope%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            9 Answers
            9






            active

            oldest

            votes








            9 Answers
            9






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            53
            down vote



            accepted










            No, there is no other way to do this - the only thing I can say is that this use case isn't very common. Like Felix said in the comment - what you do will consistently work.



            It's worth mentioning that the reason the promise constructor behaves this way is throw safety - if an exception you did not anticipate happens while your code is running inside the promise constructor it will turn into a rejection, this form of throw safety - converting thrown errors to rejections is important and helps maintain predictable code.



            For this throw safety reason, the promise constructor was chosen over deferreds (which are an alternative promise construction way that do allow what you're doing) - as for best practices - I'd pass the element and use the promise constructor instead:



            var p = new Promise(function(resolve, reject){
            this.onclick = resolve;
            }.bind(this));


            For this reason - whenever you can use the promise constructor over exporting the functions - I recommend you do use it. Whenever you can avoid both - avoid both and chain.



            Note, that you should never use the promise constructor for things like if(condition), the first example could be written as:



            var p = Promise[(someCondition)?"resolve":"reject"]();





            share|improve this answer

















            • 1




              Hi Benjamin! Is there currently no better way of getting yummy promise sugar if we don't know when the promise will be fulfilled yet? Like some sort of asynchronous wait/notify pattern? Like for example, "store", and later invoke a Promise chain? E.g. in my particular case, I am on a server, waiting for a specific client reply (a SYN-ACK-kinda hand-shake to make sure the client successfully updated state).
              – Domi
              May 3 '15 at 13:17








            • 1




              @Domi check out q-connection and RxJS.
              – Benjamin Gruenbaum
              May 3 '15 at 14:09










            • Hah, as usual, I was too impatient to wait! Either way, it seems like what those libraries are doing is overkill for my particular use-case, unless they are fixing issues that I have overlooked. Mind taking a look at my minimal solution?
              – Domi
              May 3 '15 at 14:17








            • 1




              How could do I the same using fetch API?
              – Vinod Sobale
              Apr 20 '17 at 5:05






            • 24




              Not common? I end up needing it almost every project.
              – Tomáš Zato
              Jun 23 '17 at 15:24















            up vote
            53
            down vote



            accepted










            No, there is no other way to do this - the only thing I can say is that this use case isn't very common. Like Felix said in the comment - what you do will consistently work.



            It's worth mentioning that the reason the promise constructor behaves this way is throw safety - if an exception you did not anticipate happens while your code is running inside the promise constructor it will turn into a rejection, this form of throw safety - converting thrown errors to rejections is important and helps maintain predictable code.



            For this throw safety reason, the promise constructor was chosen over deferreds (which are an alternative promise construction way that do allow what you're doing) - as for best practices - I'd pass the element and use the promise constructor instead:



            var p = new Promise(function(resolve, reject){
            this.onclick = resolve;
            }.bind(this));


            For this reason - whenever you can use the promise constructor over exporting the functions - I recommend you do use it. Whenever you can avoid both - avoid both and chain.



            Note, that you should never use the promise constructor for things like if(condition), the first example could be written as:



            var p = Promise[(someCondition)?"resolve":"reject"]();





            share|improve this answer

















            • 1




              Hi Benjamin! Is there currently no better way of getting yummy promise sugar if we don't know when the promise will be fulfilled yet? Like some sort of asynchronous wait/notify pattern? Like for example, "store", and later invoke a Promise chain? E.g. in my particular case, I am on a server, waiting for a specific client reply (a SYN-ACK-kinda hand-shake to make sure the client successfully updated state).
              – Domi
              May 3 '15 at 13:17








            • 1




              @Domi check out q-connection and RxJS.
              – Benjamin Gruenbaum
              May 3 '15 at 14:09










            • Hah, as usual, I was too impatient to wait! Either way, it seems like what those libraries are doing is overkill for my particular use-case, unless they are fixing issues that I have overlooked. Mind taking a look at my minimal solution?
              – Domi
              May 3 '15 at 14:17








            • 1




              How could do I the same using fetch API?
              – Vinod Sobale
              Apr 20 '17 at 5:05






            • 24




              Not common? I end up needing it almost every project.
              – Tomáš Zato
              Jun 23 '17 at 15:24













            up vote
            53
            down vote



            accepted







            up vote
            53
            down vote



            accepted






            No, there is no other way to do this - the only thing I can say is that this use case isn't very common. Like Felix said in the comment - what you do will consistently work.



            It's worth mentioning that the reason the promise constructor behaves this way is throw safety - if an exception you did not anticipate happens while your code is running inside the promise constructor it will turn into a rejection, this form of throw safety - converting thrown errors to rejections is important and helps maintain predictable code.



            For this throw safety reason, the promise constructor was chosen over deferreds (which are an alternative promise construction way that do allow what you're doing) - as for best practices - I'd pass the element and use the promise constructor instead:



            var p = new Promise(function(resolve, reject){
            this.onclick = resolve;
            }.bind(this));


            For this reason - whenever you can use the promise constructor over exporting the functions - I recommend you do use it. Whenever you can avoid both - avoid both and chain.



            Note, that you should never use the promise constructor for things like if(condition), the first example could be written as:



            var p = Promise[(someCondition)?"resolve":"reject"]();





            share|improve this answer












            No, there is no other way to do this - the only thing I can say is that this use case isn't very common. Like Felix said in the comment - what you do will consistently work.



            It's worth mentioning that the reason the promise constructor behaves this way is throw safety - if an exception you did not anticipate happens while your code is running inside the promise constructor it will turn into a rejection, this form of throw safety - converting thrown errors to rejections is important and helps maintain predictable code.



            For this throw safety reason, the promise constructor was chosen over deferreds (which are an alternative promise construction way that do allow what you're doing) - as for best practices - I'd pass the element and use the promise constructor instead:



            var p = new Promise(function(resolve, reject){
            this.onclick = resolve;
            }.bind(this));


            For this reason - whenever you can use the promise constructor over exporting the functions - I recommend you do use it. Whenever you can avoid both - avoid both and chain.



            Note, that you should never use the promise constructor for things like if(condition), the first example could be written as:



            var p = Promise[(someCondition)?"resolve":"reject"]();






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Oct 1 '14 at 20:53









            Benjamin Gruenbaum

            183k62397433




            183k62397433








            • 1




              Hi Benjamin! Is there currently no better way of getting yummy promise sugar if we don't know when the promise will be fulfilled yet? Like some sort of asynchronous wait/notify pattern? Like for example, "store", and later invoke a Promise chain? E.g. in my particular case, I am on a server, waiting for a specific client reply (a SYN-ACK-kinda hand-shake to make sure the client successfully updated state).
              – Domi
              May 3 '15 at 13:17








            • 1




              @Domi check out q-connection and RxJS.
              – Benjamin Gruenbaum
              May 3 '15 at 14:09










            • Hah, as usual, I was too impatient to wait! Either way, it seems like what those libraries are doing is overkill for my particular use-case, unless they are fixing issues that I have overlooked. Mind taking a look at my minimal solution?
              – Domi
              May 3 '15 at 14:17








            • 1




              How could do I the same using fetch API?
              – Vinod Sobale
              Apr 20 '17 at 5:05






            • 24




              Not common? I end up needing it almost every project.
              – Tomáš Zato
              Jun 23 '17 at 15:24














            • 1




              Hi Benjamin! Is there currently no better way of getting yummy promise sugar if we don't know when the promise will be fulfilled yet? Like some sort of asynchronous wait/notify pattern? Like for example, "store", and later invoke a Promise chain? E.g. in my particular case, I am on a server, waiting for a specific client reply (a SYN-ACK-kinda hand-shake to make sure the client successfully updated state).
              – Domi
              May 3 '15 at 13:17








            • 1




              @Domi check out q-connection and RxJS.
              – Benjamin Gruenbaum
              May 3 '15 at 14:09










            • Hah, as usual, I was too impatient to wait! Either way, it seems like what those libraries are doing is overkill for my particular use-case, unless they are fixing issues that I have overlooked. Mind taking a look at my minimal solution?
              – Domi
              May 3 '15 at 14:17








            • 1




              How could do I the same using fetch API?
              – Vinod Sobale
              Apr 20 '17 at 5:05






            • 24




              Not common? I end up needing it almost every project.
              – Tomáš Zato
              Jun 23 '17 at 15:24








            1




            1




            Hi Benjamin! Is there currently no better way of getting yummy promise sugar if we don't know when the promise will be fulfilled yet? Like some sort of asynchronous wait/notify pattern? Like for example, "store", and later invoke a Promise chain? E.g. in my particular case, I am on a server, waiting for a specific client reply (a SYN-ACK-kinda hand-shake to make sure the client successfully updated state).
            – Domi
            May 3 '15 at 13:17






            Hi Benjamin! Is there currently no better way of getting yummy promise sugar if we don't know when the promise will be fulfilled yet? Like some sort of asynchronous wait/notify pattern? Like for example, "store", and later invoke a Promise chain? E.g. in my particular case, I am on a server, waiting for a specific client reply (a SYN-ACK-kinda hand-shake to make sure the client successfully updated state).
            – Domi
            May 3 '15 at 13:17






            1




            1




            @Domi check out q-connection and RxJS.
            – Benjamin Gruenbaum
            May 3 '15 at 14:09




            @Domi check out q-connection and RxJS.
            – Benjamin Gruenbaum
            May 3 '15 at 14:09












            Hah, as usual, I was too impatient to wait! Either way, it seems like what those libraries are doing is overkill for my particular use-case, unless they are fixing issues that I have overlooked. Mind taking a look at my minimal solution?
            – Domi
            May 3 '15 at 14:17






            Hah, as usual, I was too impatient to wait! Either way, it seems like what those libraries are doing is overkill for my particular use-case, unless they are fixing issues that I have overlooked. Mind taking a look at my minimal solution?
            – Domi
            May 3 '15 at 14:17






            1




            1




            How could do I the same using fetch API?
            – Vinod Sobale
            Apr 20 '17 at 5:05




            How could do I the same using fetch API?
            – Vinod Sobale
            Apr 20 '17 at 5:05




            24




            24




            Not common? I end up needing it almost every project.
            – Tomáš Zato
            Jun 23 '17 at 15:24




            Not common? I end up needing it almost every project.
            – Tomáš Zato
            Jun 23 '17 at 15:24












            up vote
            80
            down vote













            simple:



            var promiseResolve, promiseReject;

            var promise = new Promise(function(resolve, reject){
            promiseResolve = resolve;
            promiseReject = reject;
            });

            promiseResolve();





            share|improve this answer

















            • 1




              @ruX, As the accepted answer mentions - it was designed this way on purpose. The point is that if an exception is thrown it will be caught by the promise constructor. This answer (as well as mine) has the pitfall of possibly throwing an exception for whatever code calls promiseResolve(). The semantics of a promise are that it always returns a value. Also this is functionally the same as OP's post, I don't get what problem this is solving in a reusable way.
              – Jon Jaques
              Jun 27 '16 at 20:30








            • 2




              @JonJaques I'm not sure if what you say is true. The code that calls promiseResolve() will not throw an exception. You can define a .catch on the constructor and no matter what code calls it, the constructor's .catch will be called. Here is the jsbin demonstrating how this works: jsbin.com/yicerewivo/edit?js,console
              – carter
              Jul 5 '16 at 22:26










            • Yeah, it's caught because you wrapped another promise constructor around it - Exactly the point I'm trying to make. However, lets say you have some other code that's trying to call resolve() outside of the constructor (aka Deferred object)... It could throw an exception and not be caught jsbin.com/cokiqiwapo/1/edit?js,console
              – Jon Jaques
              Jul 6 '16 at 13:26










            • I see what you mean now, but I don't see how that relates to creating flexible promise resolvers. If you throw an error outside of something that can catch it, then it doesn't get caught. This is not a pitfall of a promise pattern. This is just an example of a bad pattern.
              – carter
              Jul 12 '16 at 17:17






            • 4




              I am not even sure it is a bad design. An error thrown outside the promise isn't supposed to be caught within the promise. It is perhaps an example of misconception or bad understanding, if the designer actually expects the error to be caught within.
              – KalEl
              May 11 '17 at 22:17















            up vote
            80
            down vote













            simple:



            var promiseResolve, promiseReject;

            var promise = new Promise(function(resolve, reject){
            promiseResolve = resolve;
            promiseReject = reject;
            });

            promiseResolve();





            share|improve this answer

















            • 1




              @ruX, As the accepted answer mentions - it was designed this way on purpose. The point is that if an exception is thrown it will be caught by the promise constructor. This answer (as well as mine) has the pitfall of possibly throwing an exception for whatever code calls promiseResolve(). The semantics of a promise are that it always returns a value. Also this is functionally the same as OP's post, I don't get what problem this is solving in a reusable way.
              – Jon Jaques
              Jun 27 '16 at 20:30








            • 2




              @JonJaques I'm not sure if what you say is true. The code that calls promiseResolve() will not throw an exception. You can define a .catch on the constructor and no matter what code calls it, the constructor's .catch will be called. Here is the jsbin demonstrating how this works: jsbin.com/yicerewivo/edit?js,console
              – carter
              Jul 5 '16 at 22:26










            • Yeah, it's caught because you wrapped another promise constructor around it - Exactly the point I'm trying to make. However, lets say you have some other code that's trying to call resolve() outside of the constructor (aka Deferred object)... It could throw an exception and not be caught jsbin.com/cokiqiwapo/1/edit?js,console
              – Jon Jaques
              Jul 6 '16 at 13:26










            • I see what you mean now, but I don't see how that relates to creating flexible promise resolvers. If you throw an error outside of something that can catch it, then it doesn't get caught. This is not a pitfall of a promise pattern. This is just an example of a bad pattern.
              – carter
              Jul 12 '16 at 17:17






            • 4




              I am not even sure it is a bad design. An error thrown outside the promise isn't supposed to be caught within the promise. It is perhaps an example of misconception or bad understanding, if the designer actually expects the error to be caught within.
              – KalEl
              May 11 '17 at 22:17













            up vote
            80
            down vote










            up vote
            80
            down vote









            simple:



            var promiseResolve, promiseReject;

            var promise = new Promise(function(resolve, reject){
            promiseResolve = resolve;
            promiseReject = reject;
            });

            promiseResolve();





            share|improve this answer












            simple:



            var promiseResolve, promiseReject;

            var promise = new Promise(function(resolve, reject){
            promiseResolve = resolve;
            promiseReject = reject;
            });

            promiseResolve();






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Mar 17 '16 at 21:44









            carter

            2,54632037




            2,54632037








            • 1




              @ruX, As the accepted answer mentions - it was designed this way on purpose. The point is that if an exception is thrown it will be caught by the promise constructor. This answer (as well as mine) has the pitfall of possibly throwing an exception for whatever code calls promiseResolve(). The semantics of a promise are that it always returns a value. Also this is functionally the same as OP's post, I don't get what problem this is solving in a reusable way.
              – Jon Jaques
              Jun 27 '16 at 20:30








            • 2




              @JonJaques I'm not sure if what you say is true. The code that calls promiseResolve() will not throw an exception. You can define a .catch on the constructor and no matter what code calls it, the constructor's .catch will be called. Here is the jsbin demonstrating how this works: jsbin.com/yicerewivo/edit?js,console
              – carter
              Jul 5 '16 at 22:26










            • Yeah, it's caught because you wrapped another promise constructor around it - Exactly the point I'm trying to make. However, lets say you have some other code that's trying to call resolve() outside of the constructor (aka Deferred object)... It could throw an exception and not be caught jsbin.com/cokiqiwapo/1/edit?js,console
              – Jon Jaques
              Jul 6 '16 at 13:26










            • I see what you mean now, but I don't see how that relates to creating flexible promise resolvers. If you throw an error outside of something that can catch it, then it doesn't get caught. This is not a pitfall of a promise pattern. This is just an example of a bad pattern.
              – carter
              Jul 12 '16 at 17:17






            • 4




              I am not even sure it is a bad design. An error thrown outside the promise isn't supposed to be caught within the promise. It is perhaps an example of misconception or bad understanding, if the designer actually expects the error to be caught within.
              – KalEl
              May 11 '17 at 22:17














            • 1




              @ruX, As the accepted answer mentions - it was designed this way on purpose. The point is that if an exception is thrown it will be caught by the promise constructor. This answer (as well as mine) has the pitfall of possibly throwing an exception for whatever code calls promiseResolve(). The semantics of a promise are that it always returns a value. Also this is functionally the same as OP's post, I don't get what problem this is solving in a reusable way.
              – Jon Jaques
              Jun 27 '16 at 20:30








            • 2




              @JonJaques I'm not sure if what you say is true. The code that calls promiseResolve() will not throw an exception. You can define a .catch on the constructor and no matter what code calls it, the constructor's .catch will be called. Here is the jsbin demonstrating how this works: jsbin.com/yicerewivo/edit?js,console
              – carter
              Jul 5 '16 at 22:26










            • Yeah, it's caught because you wrapped another promise constructor around it - Exactly the point I'm trying to make. However, lets say you have some other code that's trying to call resolve() outside of the constructor (aka Deferred object)... It could throw an exception and not be caught jsbin.com/cokiqiwapo/1/edit?js,console
              – Jon Jaques
              Jul 6 '16 at 13:26










            • I see what you mean now, but I don't see how that relates to creating flexible promise resolvers. If you throw an error outside of something that can catch it, then it doesn't get caught. This is not a pitfall of a promise pattern. This is just an example of a bad pattern.
              – carter
              Jul 12 '16 at 17:17






            • 4




              I am not even sure it is a bad design. An error thrown outside the promise isn't supposed to be caught within the promise. It is perhaps an example of misconception or bad understanding, if the designer actually expects the error to be caught within.
              – KalEl
              May 11 '17 at 22:17








            1




            1




            @ruX, As the accepted answer mentions - it was designed this way on purpose. The point is that if an exception is thrown it will be caught by the promise constructor. This answer (as well as mine) has the pitfall of possibly throwing an exception for whatever code calls promiseResolve(). The semantics of a promise are that it always returns a value. Also this is functionally the same as OP's post, I don't get what problem this is solving in a reusable way.
            – Jon Jaques
            Jun 27 '16 at 20:30






            @ruX, As the accepted answer mentions - it was designed this way on purpose. The point is that if an exception is thrown it will be caught by the promise constructor. This answer (as well as mine) has the pitfall of possibly throwing an exception for whatever code calls promiseResolve(). The semantics of a promise are that it always returns a value. Also this is functionally the same as OP's post, I don't get what problem this is solving in a reusable way.
            – Jon Jaques
            Jun 27 '16 at 20:30






            2




            2




            @JonJaques I'm not sure if what you say is true. The code that calls promiseResolve() will not throw an exception. You can define a .catch on the constructor and no matter what code calls it, the constructor's .catch will be called. Here is the jsbin demonstrating how this works: jsbin.com/yicerewivo/edit?js,console
            – carter
            Jul 5 '16 at 22:26




            @JonJaques I'm not sure if what you say is true. The code that calls promiseResolve() will not throw an exception. You can define a .catch on the constructor and no matter what code calls it, the constructor's .catch will be called. Here is the jsbin demonstrating how this works: jsbin.com/yicerewivo/edit?js,console
            – carter
            Jul 5 '16 at 22:26












            Yeah, it's caught because you wrapped another promise constructor around it - Exactly the point I'm trying to make. However, lets say you have some other code that's trying to call resolve() outside of the constructor (aka Deferred object)... It could throw an exception and not be caught jsbin.com/cokiqiwapo/1/edit?js,console
            – Jon Jaques
            Jul 6 '16 at 13:26




            Yeah, it's caught because you wrapped another promise constructor around it - Exactly the point I'm trying to make. However, lets say you have some other code that's trying to call resolve() outside of the constructor (aka Deferred object)... It could throw an exception and not be caught jsbin.com/cokiqiwapo/1/edit?js,console
            – Jon Jaques
            Jul 6 '16 at 13:26












            I see what you mean now, but I don't see how that relates to creating flexible promise resolvers. If you throw an error outside of something that can catch it, then it doesn't get caught. This is not a pitfall of a promise pattern. This is just an example of a bad pattern.
            – carter
            Jul 12 '16 at 17:17




            I see what you mean now, but I don't see how that relates to creating flexible promise resolvers. If you throw an error outside of something that can catch it, then it doesn't get caught. This is not a pitfall of a promise pattern. This is just an example of a bad pattern.
            – carter
            Jul 12 '16 at 17:17




            4




            4




            I am not even sure it is a bad design. An error thrown outside the promise isn't supposed to be caught within the promise. It is perhaps an example of misconception or bad understanding, if the designer actually expects the error to be caught within.
            – KalEl
            May 11 '17 at 22:17




            I am not even sure it is a bad design. An error thrown outside the promise isn't supposed to be caught within the promise. It is perhaps an example of misconception or bad understanding, if the designer actually expects the error to be caught within.
            – KalEl
            May 11 '17 at 22:17










            up vote
            61
            down vote













            Bit late to the party here, but another way to do it would be to use a Deferred object. You essentially have the same amount of boilerplate, but it's handy if you want to pass them around and possibly resolve outside of their definition.



            Naive Implementation:



            class Deferred {
            constructor() {
            this.promise = new Promise((resolve, reject)=> {
            this.reject = reject
            this.resolve = resolve
            })
            }
            }

            function asyncAction() {
            var dfd = new Deferred()

            setTimeout(()=> {
            dfd.resolve(42)
            }, 500)

            return dfd.promise
            }

            asyncAction().then(result => {
            console.log(result) // 42
            })


            ES5 Version:



            function Deferred() {
            var self = this;
            this.promise = new Promise(function(resolve, reject) {
            self.reject = reject
            self.resolve = resolve
            })
            }

            function asyncAction() {
            var dfd = new Deferred()

            setTimeout(function() {
            dfd.resolve(42)
            }, 500)

            return dfd.promise
            }

            asyncAction().then(function(result) {
            console.log(result) // 42
            })





            share|improve this answer



















            • 1




              Do notice the lexical scoping here.
              – Florrie
              Feb 2 '16 at 20:45










            • There is no practical difference in whether resolve|reject are assigned lexically or through bind. This is just a simple implementation of the jQuery Deferred object that has been around since 1.0(ish). It works exactly like a promise, except there is no throw safety. The whole point of this question was how to save a few lines of code when creating promises.
              – Jon Jaques
              Jul 13 '16 at 0:08










            • Using a deferred is the usual way to do this, I have no idea why this isn't higher
              – BlueRaja - Danny Pflughoeft
              Feb 28 '17 at 22:21












            • Excellent answer! Was looking for the deferred functionality that jQuery offers.
              – Anshul Koka
              Mar 28 '17 at 22:16






            • 1




              Is Deferred deprecated?
              – Pacerier
              Oct 16 '17 at 1:34















            up vote
            61
            down vote













            Bit late to the party here, but another way to do it would be to use a Deferred object. You essentially have the same amount of boilerplate, but it's handy if you want to pass them around and possibly resolve outside of their definition.



            Naive Implementation:



            class Deferred {
            constructor() {
            this.promise = new Promise((resolve, reject)=> {
            this.reject = reject
            this.resolve = resolve
            })
            }
            }

            function asyncAction() {
            var dfd = new Deferred()

            setTimeout(()=> {
            dfd.resolve(42)
            }, 500)

            return dfd.promise
            }

            asyncAction().then(result => {
            console.log(result) // 42
            })


            ES5 Version:



            function Deferred() {
            var self = this;
            this.promise = new Promise(function(resolve, reject) {
            self.reject = reject
            self.resolve = resolve
            })
            }

            function asyncAction() {
            var dfd = new Deferred()

            setTimeout(function() {
            dfd.resolve(42)
            }, 500)

            return dfd.promise
            }

            asyncAction().then(function(result) {
            console.log(result) // 42
            })





            share|improve this answer



















            • 1




              Do notice the lexical scoping here.
              – Florrie
              Feb 2 '16 at 20:45










            • There is no practical difference in whether resolve|reject are assigned lexically or through bind. This is just a simple implementation of the jQuery Deferred object that has been around since 1.0(ish). It works exactly like a promise, except there is no throw safety. The whole point of this question was how to save a few lines of code when creating promises.
              – Jon Jaques
              Jul 13 '16 at 0:08










            • Using a deferred is the usual way to do this, I have no idea why this isn't higher
              – BlueRaja - Danny Pflughoeft
              Feb 28 '17 at 22:21












            • Excellent answer! Was looking for the deferred functionality that jQuery offers.
              – Anshul Koka
              Mar 28 '17 at 22:16






            • 1




              Is Deferred deprecated?
              – Pacerier
              Oct 16 '17 at 1:34













            up vote
            61
            down vote










            up vote
            61
            down vote









            Bit late to the party here, but another way to do it would be to use a Deferred object. You essentially have the same amount of boilerplate, but it's handy if you want to pass them around and possibly resolve outside of their definition.



            Naive Implementation:



            class Deferred {
            constructor() {
            this.promise = new Promise((resolve, reject)=> {
            this.reject = reject
            this.resolve = resolve
            })
            }
            }

            function asyncAction() {
            var dfd = new Deferred()

            setTimeout(()=> {
            dfd.resolve(42)
            }, 500)

            return dfd.promise
            }

            asyncAction().then(result => {
            console.log(result) // 42
            })


            ES5 Version:



            function Deferred() {
            var self = this;
            this.promise = new Promise(function(resolve, reject) {
            self.reject = reject
            self.resolve = resolve
            })
            }

            function asyncAction() {
            var dfd = new Deferred()

            setTimeout(function() {
            dfd.resolve(42)
            }, 500)

            return dfd.promise
            }

            asyncAction().then(function(result) {
            console.log(result) // 42
            })





            share|improve this answer














            Bit late to the party here, but another way to do it would be to use a Deferred object. You essentially have the same amount of boilerplate, but it's handy if you want to pass them around and possibly resolve outside of their definition.



            Naive Implementation:



            class Deferred {
            constructor() {
            this.promise = new Promise((resolve, reject)=> {
            this.reject = reject
            this.resolve = resolve
            })
            }
            }

            function asyncAction() {
            var dfd = new Deferred()

            setTimeout(()=> {
            dfd.resolve(42)
            }, 500)

            return dfd.promise
            }

            asyncAction().then(result => {
            console.log(result) // 42
            })


            ES5 Version:



            function Deferred() {
            var self = this;
            this.promise = new Promise(function(resolve, reject) {
            self.reject = reject
            self.resolve = resolve
            })
            }

            function asyncAction() {
            var dfd = new Deferred()

            setTimeout(function() {
            dfd.resolve(42)
            }, 500)

            return dfd.promise
            }

            asyncAction().then(function(result) {
            console.log(result) // 42
            })






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jun 27 '16 at 20:35

























            answered Jan 6 '16 at 16:02









            Jon Jaques

            2,9791722




            2,9791722








            • 1




              Do notice the lexical scoping here.
              – Florrie
              Feb 2 '16 at 20:45










            • There is no practical difference in whether resolve|reject are assigned lexically or through bind. This is just a simple implementation of the jQuery Deferred object that has been around since 1.0(ish). It works exactly like a promise, except there is no throw safety. The whole point of this question was how to save a few lines of code when creating promises.
              – Jon Jaques
              Jul 13 '16 at 0:08










            • Using a deferred is the usual way to do this, I have no idea why this isn't higher
              – BlueRaja - Danny Pflughoeft
              Feb 28 '17 at 22:21












            • Excellent answer! Was looking for the deferred functionality that jQuery offers.
              – Anshul Koka
              Mar 28 '17 at 22:16






            • 1




              Is Deferred deprecated?
              – Pacerier
              Oct 16 '17 at 1:34














            • 1




              Do notice the lexical scoping here.
              – Florrie
              Feb 2 '16 at 20:45










            • There is no practical difference in whether resolve|reject are assigned lexically or through bind. This is just a simple implementation of the jQuery Deferred object that has been around since 1.0(ish). It works exactly like a promise, except there is no throw safety. The whole point of this question was how to save a few lines of code when creating promises.
              – Jon Jaques
              Jul 13 '16 at 0:08










            • Using a deferred is the usual way to do this, I have no idea why this isn't higher
              – BlueRaja - Danny Pflughoeft
              Feb 28 '17 at 22:21












            • Excellent answer! Was looking for the deferred functionality that jQuery offers.
              – Anshul Koka
              Mar 28 '17 at 22:16






            • 1




              Is Deferred deprecated?
              – Pacerier
              Oct 16 '17 at 1:34








            1




            1




            Do notice the lexical scoping here.
            – Florrie
            Feb 2 '16 at 20:45




            Do notice the lexical scoping here.
            – Florrie
            Feb 2 '16 at 20:45












            There is no practical difference in whether resolve|reject are assigned lexically or through bind. This is just a simple implementation of the jQuery Deferred object that has been around since 1.0(ish). It works exactly like a promise, except there is no throw safety. The whole point of this question was how to save a few lines of code when creating promises.
            – Jon Jaques
            Jul 13 '16 at 0:08




            There is no practical difference in whether resolve|reject are assigned lexically or through bind. This is just a simple implementation of the jQuery Deferred object that has been around since 1.0(ish). It works exactly like a promise, except there is no throw safety. The whole point of this question was how to save a few lines of code when creating promises.
            – Jon Jaques
            Jul 13 '16 at 0:08












            Using a deferred is the usual way to do this, I have no idea why this isn't higher
            – BlueRaja - Danny Pflughoeft
            Feb 28 '17 at 22:21






            Using a deferred is the usual way to do this, I have no idea why this isn't higher
            – BlueRaja - Danny Pflughoeft
            Feb 28 '17 at 22:21














            Excellent answer! Was looking for the deferred functionality that jQuery offers.
            – Anshul Koka
            Mar 28 '17 at 22:16




            Excellent answer! Was looking for the deferred functionality that jQuery offers.
            – Anshul Koka
            Mar 28 '17 at 22:16




            1




            1




            Is Deferred deprecated?
            – Pacerier
            Oct 16 '17 at 1:34




            Is Deferred deprecated?
            – Pacerier
            Oct 16 '17 at 1:34










            up vote
            12
            down vote













            A solution I came up with in 2015 for my framework. I called this type of promises Task



            function createPromise(handler){
            var _resolve, _reject;

            var promise = new Promise(function(resolve, reject){
            _resolve = resolve;
            _reject = reject;

            handler(resolve, reject);
            })

            promise.resolve = _resolve;
            promise.reject = _reject;

            return promise;
            }

            var promise = createPromise()
            promise.then(function(data){ alert(data) })

            promise.resolve(200) // resolve from outside





            share|improve this answer



























              up vote
              12
              down vote













              A solution I came up with in 2015 for my framework. I called this type of promises Task



              function createPromise(handler){
              var _resolve, _reject;

              var promise = new Promise(function(resolve, reject){
              _resolve = resolve;
              _reject = reject;

              handler(resolve, reject);
              })

              promise.resolve = _resolve;
              promise.reject = _reject;

              return promise;
              }

              var promise = createPromise()
              promise.then(function(data){ alert(data) })

              promise.resolve(200) // resolve from outside





              share|improve this answer

























                up vote
                12
                down vote










                up vote
                12
                down vote









                A solution I came up with in 2015 for my framework. I called this type of promises Task



                function createPromise(handler){
                var _resolve, _reject;

                var promise = new Promise(function(resolve, reject){
                _resolve = resolve;
                _reject = reject;

                handler(resolve, reject);
                })

                promise.resolve = _resolve;
                promise.reject = _reject;

                return promise;
                }

                var promise = createPromise()
                promise.then(function(data){ alert(data) })

                promise.resolve(200) // resolve from outside





                share|improve this answer














                A solution I came up with in 2015 for my framework. I called this type of promises Task



                function createPromise(handler){
                var _resolve, _reject;

                var promise = new Promise(function(resolve, reject){
                _resolve = resolve;
                _reject = reject;

                handler(resolve, reject);
                })

                promise.resolve = _resolve;
                promise.reject = _reject;

                return promise;
                }

                var promise = createPromise()
                promise.then(function(data){ alert(data) })

                promise.resolve(200) // resolve from outside






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Apr 25 at 3:31









                Boaz

                14.7k74155




                14.7k74155










                answered Jul 28 '17 at 0:42









                Maxmaxmaximus

                1,1511313




                1,1511313






















                    up vote
                    7
                    down vote













                    I liked @JonJaques answer but I wanted to take it a step further.



                    If you bind then and catch then the Deferred object, then it fully implements the Promise API and you can treat it as promise and await it and such.






                    class DeferredPromise {
                    constructor() {
                    this._promise = new Promise((resolve, reject) => {
                    // assign the resolve and reject functions to `this`
                    // making them usable on the class instance
                    this.resolve = resolve;
                    this.reject = reject;
                    });
                    // bind `then` and `catch` to implement the same interface as Promise
                    this.then = this._promise.then.bind(this._promise);
                    this.catch = this._promise.catch.bind(this._promise);
                    this[Symbol.toStringTag] = 'Promise';
                    }
                    }

                    const deferred = new DeferredPromise();
                    console.log('waiting 2 seconds...');
                    setTimeout(() => {
                    deferred.resolve('whoa!');
                    }, 2000);

                    async function someAsyncFunction() {
                    const value = await deferred;
                    console.log(value);
                    }

                    someAsyncFunction();








                    share|improve this answer

























                      up vote
                      7
                      down vote













                      I liked @JonJaques answer but I wanted to take it a step further.



                      If you bind then and catch then the Deferred object, then it fully implements the Promise API and you can treat it as promise and await it and such.






                      class DeferredPromise {
                      constructor() {
                      this._promise = new Promise((resolve, reject) => {
                      // assign the resolve and reject functions to `this`
                      // making them usable on the class instance
                      this.resolve = resolve;
                      this.reject = reject;
                      });
                      // bind `then` and `catch` to implement the same interface as Promise
                      this.then = this._promise.then.bind(this._promise);
                      this.catch = this._promise.catch.bind(this._promise);
                      this[Symbol.toStringTag] = 'Promise';
                      }
                      }

                      const deferred = new DeferredPromise();
                      console.log('waiting 2 seconds...');
                      setTimeout(() => {
                      deferred.resolve('whoa!');
                      }, 2000);

                      async function someAsyncFunction() {
                      const value = await deferred;
                      console.log(value);
                      }

                      someAsyncFunction();








                      share|improve this answer























                        up vote
                        7
                        down vote










                        up vote
                        7
                        down vote









                        I liked @JonJaques answer but I wanted to take it a step further.



                        If you bind then and catch then the Deferred object, then it fully implements the Promise API and you can treat it as promise and await it and such.






                        class DeferredPromise {
                        constructor() {
                        this._promise = new Promise((resolve, reject) => {
                        // assign the resolve and reject functions to `this`
                        // making them usable on the class instance
                        this.resolve = resolve;
                        this.reject = reject;
                        });
                        // bind `then` and `catch` to implement the same interface as Promise
                        this.then = this._promise.then.bind(this._promise);
                        this.catch = this._promise.catch.bind(this._promise);
                        this[Symbol.toStringTag] = 'Promise';
                        }
                        }

                        const deferred = new DeferredPromise();
                        console.log('waiting 2 seconds...');
                        setTimeout(() => {
                        deferred.resolve('whoa!');
                        }, 2000);

                        async function someAsyncFunction() {
                        const value = await deferred;
                        console.log(value);
                        }

                        someAsyncFunction();








                        share|improve this answer












                        I liked @JonJaques answer but I wanted to take it a step further.



                        If you bind then and catch then the Deferred object, then it fully implements the Promise API and you can treat it as promise and await it and such.






                        class DeferredPromise {
                        constructor() {
                        this._promise = new Promise((resolve, reject) => {
                        // assign the resolve and reject functions to `this`
                        // making them usable on the class instance
                        this.resolve = resolve;
                        this.reject = reject;
                        });
                        // bind `then` and `catch` to implement the same interface as Promise
                        this.then = this._promise.then.bind(this._promise);
                        this.catch = this._promise.catch.bind(this._promise);
                        this[Symbol.toStringTag] = 'Promise';
                        }
                        }

                        const deferred = new DeferredPromise();
                        console.log('waiting 2 seconds...');
                        setTimeout(() => {
                        deferred.resolve('whoa!');
                        }, 2000);

                        async function someAsyncFunction() {
                        const value = await deferred;
                        console.log(value);
                        }

                        someAsyncFunction();








                        class DeferredPromise {
                        constructor() {
                        this._promise = new Promise((resolve, reject) => {
                        // assign the resolve and reject functions to `this`
                        // making them usable on the class instance
                        this.resolve = resolve;
                        this.reject = reject;
                        });
                        // bind `then` and `catch` to implement the same interface as Promise
                        this.then = this._promise.then.bind(this._promise);
                        this.catch = this._promise.catch.bind(this._promise);
                        this[Symbol.toStringTag] = 'Promise';
                        }
                        }

                        const deferred = new DeferredPromise();
                        console.log('waiting 2 seconds...');
                        setTimeout(() => {
                        deferred.resolve('whoa!');
                        }, 2000);

                        async function someAsyncFunction() {
                        const value = await deferred;
                        console.log(value);
                        }

                        someAsyncFunction();





                        class DeferredPromise {
                        constructor() {
                        this._promise = new Promise((resolve, reject) => {
                        // assign the resolve and reject functions to `this`
                        // making them usable on the class instance
                        this.resolve = resolve;
                        this.reject = reject;
                        });
                        // bind `then` and `catch` to implement the same interface as Promise
                        this.then = this._promise.then.bind(this._promise);
                        this.catch = this._promise.catch.bind(this._promise);
                        this[Symbol.toStringTag] = 'Promise';
                        }
                        }

                        const deferred = new DeferredPromise();
                        console.log('waiting 2 seconds...');
                        setTimeout(() => {
                        deferred.resolve('whoa!');
                        }, 2000);

                        async function someAsyncFunction() {
                        const value = await deferred;
                        console.log(value);
                        }

                        someAsyncFunction();






                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        answered Nov 4 '17 at 15:13









                        Rico Kahler

                        4,31131931




                        4,31131931






















                            up vote
                            5
                            down vote













                            A helper method would alleviate this extra overhead, and give you the same jQuery feel.



                            function Deferred() {
                            let resolve;
                            let reject;
                            const promise = new Promise((res, rej) => {
                            resolve = res;
                            reject = rej;
                            });
                            return { promise, resolve, reject };
                            }


                            Usage would be



                            const { promise, resolve, reject } = Deferred();
                            displayConfirmationDialog({
                            confirm: resolve,
                            cancel: reject
                            });
                            return promise;


                            Which is similar to jQuery



                            const dfd = $.Deferred();
                            displayConfirmationDialog({
                            confirm: dfd.resolve,
                            cancel: dfd.reject
                            });
                            return dfd.promise();




                            Although, in a use case this simple, native syntax is fine



                            return new Promise((resolve, reject) => {
                            displayConfirmationDialog({
                            confirm: resolve,
                            cancel: reject
                            });
                            });





                            share|improve this answer



























                              up vote
                              5
                              down vote













                              A helper method would alleviate this extra overhead, and give you the same jQuery feel.



                              function Deferred() {
                              let resolve;
                              let reject;
                              const promise = new Promise((res, rej) => {
                              resolve = res;
                              reject = rej;
                              });
                              return { promise, resolve, reject };
                              }


                              Usage would be



                              const { promise, resolve, reject } = Deferred();
                              displayConfirmationDialog({
                              confirm: resolve,
                              cancel: reject
                              });
                              return promise;


                              Which is similar to jQuery



                              const dfd = $.Deferred();
                              displayConfirmationDialog({
                              confirm: dfd.resolve,
                              cancel: dfd.reject
                              });
                              return dfd.promise();




                              Although, in a use case this simple, native syntax is fine



                              return new Promise((resolve, reject) => {
                              displayConfirmationDialog({
                              confirm: resolve,
                              cancel: reject
                              });
                              });





                              share|improve this answer

























                                up vote
                                5
                                down vote










                                up vote
                                5
                                down vote









                                A helper method would alleviate this extra overhead, and give you the same jQuery feel.



                                function Deferred() {
                                let resolve;
                                let reject;
                                const promise = new Promise((res, rej) => {
                                resolve = res;
                                reject = rej;
                                });
                                return { promise, resolve, reject };
                                }


                                Usage would be



                                const { promise, resolve, reject } = Deferred();
                                displayConfirmationDialog({
                                confirm: resolve,
                                cancel: reject
                                });
                                return promise;


                                Which is similar to jQuery



                                const dfd = $.Deferred();
                                displayConfirmationDialog({
                                confirm: dfd.resolve,
                                cancel: dfd.reject
                                });
                                return dfd.promise();




                                Although, in a use case this simple, native syntax is fine



                                return new Promise((resolve, reject) => {
                                displayConfirmationDialog({
                                confirm: resolve,
                                cancel: reject
                                });
                                });





                                share|improve this answer














                                A helper method would alleviate this extra overhead, and give you the same jQuery feel.



                                function Deferred() {
                                let resolve;
                                let reject;
                                const promise = new Promise((res, rej) => {
                                resolve = res;
                                reject = rej;
                                });
                                return { promise, resolve, reject };
                                }


                                Usage would be



                                const { promise, resolve, reject } = Deferred();
                                displayConfirmationDialog({
                                confirm: resolve,
                                cancel: reject
                                });
                                return promise;


                                Which is similar to jQuery



                                const dfd = $.Deferred();
                                displayConfirmationDialog({
                                confirm: dfd.resolve,
                                cancel: dfd.reject
                                });
                                return dfd.promise();




                                Although, in a use case this simple, native syntax is fine



                                return new Promise((resolve, reject) => {
                                displayConfirmationDialog({
                                confirm: resolve,
                                cancel: reject
                                });
                                });






                                share|improve this answer














                                share|improve this answer



                                share|improve this answer








                                edited Feb 3 at 1:05

























                                answered Feb 3 at 0:58









                                Cory Danielson

                                9,60023140




                                9,60023140






















                                    up vote
                                    2
                                    down vote













                                    Our solution was to use closures to store the resolve/reject functions and additionally attach a function to extend the promise itself.



                                    Here is the pattern:



                                    function getPromise() {

                                    var _resolve, _reject;

                                    var promise = new Promise((resolve, reject) => {
                                    _reject = reject;
                                    _resolve = resolve;
                                    });

                                    promise.resolve_ex = (value) => {
                                    _resolve(value);
                                    };

                                    promise.reject_ex = (value) => {
                                    _reject(value);
                                    };

                                    return promise;
                                    }


                                    And using it:



                                    var promise = getPromise();

                                    promise.then(value => {
                                    console.info('The promise has been fulfilled: ' + value);
                                    });

                                    promise.resolve_ex('hello');
                                    // or the reject version
                                    //promise.reject_ex('goodbye');





                                    share|improve this answer



















                                    • 2




                                      Great... I'm just learning Promises but have been consistently puzzled by the fact that you don't appear to be able to resolve them "somewhere else". Using a closure to hide implementation details is a great idea... but in fact I'm not sure that's what you've done: rather than have "pseudo" private variables I'm pretty sure there's a way to completely conceal the variables which should be inaccessible... which is really what closures mean...
                                      – mike rodent
                                      Jul 3 '17 at 18:05










                                    • > A closure is a block of code that can be referenced (and passed around) with access to the variables of the enclosing scope. var _resolve, _reject; are the enclosing scope.
                                      – Steven Spungin
                                      Jul 3 '17 at 20:12












                                    • yep, fair enough. Actually it seems to me that my answer is overcomplicating things, and furthermore that your answer can be simplified: you just need to go promise.resolve_ex = _resolve; promise.reject_ex = _reject; ... still works fine.
                                      – mike rodent
                                      Jul 3 '17 at 21:03










                                    • "attach a function to extend the promise itself." - don't do that. Promises are result values, they should not provide the capability to resolve them. You don't want to pass those extended ones around.
                                      – Bergi
                                      Jul 4 '17 at 16:41








                                    • 2




                                      The question was how to resolve it outside of the scope. Here is a solution that works, and in our production we have actually had a necessary reason to do it. I don't see why solving the problem stated deserves a downvote.
                                      – Steven Spungin
                                      Jul 4 '17 at 20:46















                                    up vote
                                    2
                                    down vote













                                    Our solution was to use closures to store the resolve/reject functions and additionally attach a function to extend the promise itself.



                                    Here is the pattern:



                                    function getPromise() {

                                    var _resolve, _reject;

                                    var promise = new Promise((resolve, reject) => {
                                    _reject = reject;
                                    _resolve = resolve;
                                    });

                                    promise.resolve_ex = (value) => {
                                    _resolve(value);
                                    };

                                    promise.reject_ex = (value) => {
                                    _reject(value);
                                    };

                                    return promise;
                                    }


                                    And using it:



                                    var promise = getPromise();

                                    promise.then(value => {
                                    console.info('The promise has been fulfilled: ' + value);
                                    });

                                    promise.resolve_ex('hello');
                                    // or the reject version
                                    //promise.reject_ex('goodbye');





                                    share|improve this answer



















                                    • 2




                                      Great... I'm just learning Promises but have been consistently puzzled by the fact that you don't appear to be able to resolve them "somewhere else". Using a closure to hide implementation details is a great idea... but in fact I'm not sure that's what you've done: rather than have "pseudo" private variables I'm pretty sure there's a way to completely conceal the variables which should be inaccessible... which is really what closures mean...
                                      – mike rodent
                                      Jul 3 '17 at 18:05










                                    • > A closure is a block of code that can be referenced (and passed around) with access to the variables of the enclosing scope. var _resolve, _reject; are the enclosing scope.
                                      – Steven Spungin
                                      Jul 3 '17 at 20:12












                                    • yep, fair enough. Actually it seems to me that my answer is overcomplicating things, and furthermore that your answer can be simplified: you just need to go promise.resolve_ex = _resolve; promise.reject_ex = _reject; ... still works fine.
                                      – mike rodent
                                      Jul 3 '17 at 21:03










                                    • "attach a function to extend the promise itself." - don't do that. Promises are result values, they should not provide the capability to resolve them. You don't want to pass those extended ones around.
                                      – Bergi
                                      Jul 4 '17 at 16:41








                                    • 2




                                      The question was how to resolve it outside of the scope. Here is a solution that works, and in our production we have actually had a necessary reason to do it. I don't see why solving the problem stated deserves a downvote.
                                      – Steven Spungin
                                      Jul 4 '17 at 20:46













                                    up vote
                                    2
                                    down vote










                                    up vote
                                    2
                                    down vote









                                    Our solution was to use closures to store the resolve/reject functions and additionally attach a function to extend the promise itself.



                                    Here is the pattern:



                                    function getPromise() {

                                    var _resolve, _reject;

                                    var promise = new Promise((resolve, reject) => {
                                    _reject = reject;
                                    _resolve = resolve;
                                    });

                                    promise.resolve_ex = (value) => {
                                    _resolve(value);
                                    };

                                    promise.reject_ex = (value) => {
                                    _reject(value);
                                    };

                                    return promise;
                                    }


                                    And using it:



                                    var promise = getPromise();

                                    promise.then(value => {
                                    console.info('The promise has been fulfilled: ' + value);
                                    });

                                    promise.resolve_ex('hello');
                                    // or the reject version
                                    //promise.reject_ex('goodbye');





                                    share|improve this answer














                                    Our solution was to use closures to store the resolve/reject functions and additionally attach a function to extend the promise itself.



                                    Here is the pattern:



                                    function getPromise() {

                                    var _resolve, _reject;

                                    var promise = new Promise((resolve, reject) => {
                                    _reject = reject;
                                    _resolve = resolve;
                                    });

                                    promise.resolve_ex = (value) => {
                                    _resolve(value);
                                    };

                                    promise.reject_ex = (value) => {
                                    _reject(value);
                                    };

                                    return promise;
                                    }


                                    And using it:



                                    var promise = getPromise();

                                    promise.then(value => {
                                    console.info('The promise has been fulfilled: ' + value);
                                    });

                                    promise.resolve_ex('hello');
                                    // or the reject version
                                    //promise.reject_ex('goodbye');






                                    share|improve this answer














                                    share|improve this answer



                                    share|improve this answer








                                    edited Jan 13 '17 at 13:02

























                                    answered Jan 12 '17 at 2:59









                                    Steven Spungin

                                    6,30322230




                                    6,30322230








                                    • 2




                                      Great... I'm just learning Promises but have been consistently puzzled by the fact that you don't appear to be able to resolve them "somewhere else". Using a closure to hide implementation details is a great idea... but in fact I'm not sure that's what you've done: rather than have "pseudo" private variables I'm pretty sure there's a way to completely conceal the variables which should be inaccessible... which is really what closures mean...
                                      – mike rodent
                                      Jul 3 '17 at 18:05










                                    • > A closure is a block of code that can be referenced (and passed around) with access to the variables of the enclosing scope. var _resolve, _reject; are the enclosing scope.
                                      – Steven Spungin
                                      Jul 3 '17 at 20:12












                                    • yep, fair enough. Actually it seems to me that my answer is overcomplicating things, and furthermore that your answer can be simplified: you just need to go promise.resolve_ex = _resolve; promise.reject_ex = _reject; ... still works fine.
                                      – mike rodent
                                      Jul 3 '17 at 21:03










                                    • "attach a function to extend the promise itself." - don't do that. Promises are result values, they should not provide the capability to resolve them. You don't want to pass those extended ones around.
                                      – Bergi
                                      Jul 4 '17 at 16:41








                                    • 2




                                      The question was how to resolve it outside of the scope. Here is a solution that works, and in our production we have actually had a necessary reason to do it. I don't see why solving the problem stated deserves a downvote.
                                      – Steven Spungin
                                      Jul 4 '17 at 20:46














                                    • 2




                                      Great... I'm just learning Promises but have been consistently puzzled by the fact that you don't appear to be able to resolve them "somewhere else". Using a closure to hide implementation details is a great idea... but in fact I'm not sure that's what you've done: rather than have "pseudo" private variables I'm pretty sure there's a way to completely conceal the variables which should be inaccessible... which is really what closures mean...
                                      – mike rodent
                                      Jul 3 '17 at 18:05










                                    • > A closure is a block of code that can be referenced (and passed around) with access to the variables of the enclosing scope. var _resolve, _reject; are the enclosing scope.
                                      – Steven Spungin
                                      Jul 3 '17 at 20:12












                                    • yep, fair enough. Actually it seems to me that my answer is overcomplicating things, and furthermore that your answer can be simplified: you just need to go promise.resolve_ex = _resolve; promise.reject_ex = _reject; ... still works fine.
                                      – mike rodent
                                      Jul 3 '17 at 21:03










                                    • "attach a function to extend the promise itself." - don't do that. Promises are result values, they should not provide the capability to resolve them. You don't want to pass those extended ones around.
                                      – Bergi
                                      Jul 4 '17 at 16:41








                                    • 2




                                      The question was how to resolve it outside of the scope. Here is a solution that works, and in our production we have actually had a necessary reason to do it. I don't see why solving the problem stated deserves a downvote.
                                      – Steven Spungin
                                      Jul 4 '17 at 20:46








                                    2




                                    2




                                    Great... I'm just learning Promises but have been consistently puzzled by the fact that you don't appear to be able to resolve them "somewhere else". Using a closure to hide implementation details is a great idea... but in fact I'm not sure that's what you've done: rather than have "pseudo" private variables I'm pretty sure there's a way to completely conceal the variables which should be inaccessible... which is really what closures mean...
                                    – mike rodent
                                    Jul 3 '17 at 18:05




                                    Great... I'm just learning Promises but have been consistently puzzled by the fact that you don't appear to be able to resolve them "somewhere else". Using a closure to hide implementation details is a great idea... but in fact I'm not sure that's what you've done: rather than have "pseudo" private variables I'm pretty sure there's a way to completely conceal the variables which should be inaccessible... which is really what closures mean...
                                    – mike rodent
                                    Jul 3 '17 at 18:05












                                    > A closure is a block of code that can be referenced (and passed around) with access to the variables of the enclosing scope. var _resolve, _reject; are the enclosing scope.
                                    – Steven Spungin
                                    Jul 3 '17 at 20:12






                                    > A closure is a block of code that can be referenced (and passed around) with access to the variables of the enclosing scope. var _resolve, _reject; are the enclosing scope.
                                    – Steven Spungin
                                    Jul 3 '17 at 20:12














                                    yep, fair enough. Actually it seems to me that my answer is overcomplicating things, and furthermore that your answer can be simplified: you just need to go promise.resolve_ex = _resolve; promise.reject_ex = _reject; ... still works fine.
                                    – mike rodent
                                    Jul 3 '17 at 21:03




                                    yep, fair enough. Actually it seems to me that my answer is overcomplicating things, and furthermore that your answer can be simplified: you just need to go promise.resolve_ex = _resolve; promise.reject_ex = _reject; ... still works fine.
                                    – mike rodent
                                    Jul 3 '17 at 21:03












                                    "attach a function to extend the promise itself." - don't do that. Promises are result values, they should not provide the capability to resolve them. You don't want to pass those extended ones around.
                                    – Bergi
                                    Jul 4 '17 at 16:41






                                    "attach a function to extend the promise itself." - don't do that. Promises are result values, they should not provide the capability to resolve them. You don't want to pass those extended ones around.
                                    – Bergi
                                    Jul 4 '17 at 16:41






                                    2




                                    2




                                    The question was how to resolve it outside of the scope. Here is a solution that works, and in our production we have actually had a necessary reason to do it. I don't see why solving the problem stated deserves a downvote.
                                    – Steven Spungin
                                    Jul 4 '17 at 20:46




                                    The question was how to resolve it outside of the scope. Here is a solution that works, and in our production we have actually had a necessary reason to do it. I don't see why solving the problem stated deserves a downvote.
                                    – Steven Spungin
                                    Jul 4 '17 at 20:46










                                    up vote
                                    0
                                    down vote













                                    I wrote a small lib for this. https://www.npmjs.com/package/@inf3rno/promise.exposed



                                    I used the factory method approach others wrote, but I overrode the then, catch, finally methods too, so you can resolve the original promise by those as well.



                                    Resolving Promise without executor from outside:



                                    const promise = Promise.exposed().then(console.log);
                                    promise.resolve("This should show up in the console.");


                                    Racing with the executor's setTimeout from outside:



                                    const promise = Promise.exposed(function (resolve, reject){
                                    setTimeout(function (){
                                    resolve("I almost fell asleep.")
                                    }, 100000);
                                    }).then(console.log);

                                    setTimeout(function (){
                                    promise.resolve("I don't want to wait that much.");
                                    }, 100);


                                    There is a no-conflict mode if you don't want to pollute the global namespace:



                                    const createExposedPromise = require("@inf3rno/promise.exposed/noConflict");
                                    const promise = createExposedPromise().then(console.log);
                                    promise.resolve("This should show up in the console.");





                                    share|improve this answer

























                                      up vote
                                      0
                                      down vote













                                      I wrote a small lib for this. https://www.npmjs.com/package/@inf3rno/promise.exposed



                                      I used the factory method approach others wrote, but I overrode the then, catch, finally methods too, so you can resolve the original promise by those as well.



                                      Resolving Promise without executor from outside:



                                      const promise = Promise.exposed().then(console.log);
                                      promise.resolve("This should show up in the console.");


                                      Racing with the executor's setTimeout from outside:



                                      const promise = Promise.exposed(function (resolve, reject){
                                      setTimeout(function (){
                                      resolve("I almost fell asleep.")
                                      }, 100000);
                                      }).then(console.log);

                                      setTimeout(function (){
                                      promise.resolve("I don't want to wait that much.");
                                      }, 100);


                                      There is a no-conflict mode if you don't want to pollute the global namespace:



                                      const createExposedPromise = require("@inf3rno/promise.exposed/noConflict");
                                      const promise = createExposedPromise().then(console.log);
                                      promise.resolve("This should show up in the console.");





                                      share|improve this answer























                                        up vote
                                        0
                                        down vote










                                        up vote
                                        0
                                        down vote









                                        I wrote a small lib for this. https://www.npmjs.com/package/@inf3rno/promise.exposed



                                        I used the factory method approach others wrote, but I overrode the then, catch, finally methods too, so you can resolve the original promise by those as well.



                                        Resolving Promise without executor from outside:



                                        const promise = Promise.exposed().then(console.log);
                                        promise.resolve("This should show up in the console.");


                                        Racing with the executor's setTimeout from outside:



                                        const promise = Promise.exposed(function (resolve, reject){
                                        setTimeout(function (){
                                        resolve("I almost fell asleep.")
                                        }, 100000);
                                        }).then(console.log);

                                        setTimeout(function (){
                                        promise.resolve("I don't want to wait that much.");
                                        }, 100);


                                        There is a no-conflict mode if you don't want to pollute the global namespace:



                                        const createExposedPromise = require("@inf3rno/promise.exposed/noConflict");
                                        const promise = createExposedPromise().then(console.log);
                                        promise.resolve("This should show up in the console.");





                                        share|improve this answer












                                        I wrote a small lib for this. https://www.npmjs.com/package/@inf3rno/promise.exposed



                                        I used the factory method approach others wrote, but I overrode the then, catch, finally methods too, so you can resolve the original promise by those as well.



                                        Resolving Promise without executor from outside:



                                        const promise = Promise.exposed().then(console.log);
                                        promise.resolve("This should show up in the console.");


                                        Racing with the executor's setTimeout from outside:



                                        const promise = Promise.exposed(function (resolve, reject){
                                        setTimeout(function (){
                                        resolve("I almost fell asleep.")
                                        }, 100000);
                                        }).then(console.log);

                                        setTimeout(function (){
                                        promise.resolve("I don't want to wait that much.");
                                        }, 100);


                                        There is a no-conflict mode if you don't want to pollute the global namespace:



                                        const createExposedPromise = require("@inf3rno/promise.exposed/noConflict");
                                        const promise = createExposedPromise().then(console.log);
                                        promise.resolve("This should show up in the console.");






                                        share|improve this answer












                                        share|improve this answer



                                        share|improve this answer










                                        answered Oct 31 at 11:27









                                        inf3rno

                                        14.2k774124




                                        14.2k774124






















                                            up vote
                                            0
                                            down vote













                                            I'm using a helper function to create what I call a "flat promise" -



                                            function flatPromise() {

                                            let resolve, reject;

                                            const promise = new Promise((res, rej) => {
                                            resolve = res;
                                            reject = rej;
                                            });

                                            return { promise, resolve, reject };
                                            }


                                            And I'm using it like so -



                                            function doSomethingAsync() {

                                            // Get your promise and callbacks
                                            const { resolve, reject, promise } = flatPromise();

                                            // Do something amazing...
                                            setTimeout(() => {
                                            resolve('done!');
                                            }, 500);

                                            // Pass your promise to the world
                                            return promise;

                                            }


                                            See full working example -






                                            function flatPromise() {

                                            let resolve, reject;

                                            const promise = new Promise((res, rej) => {
                                            resolve = res;
                                            reject = rej;
                                            });

                                            return { promise, resolve, reject };
                                            }

                                            function doSomethingAsync() {

                                            // Get your promise and callbacks
                                            const { resolve, reject, promise } = flatPromise();

                                            // Do something amazing...
                                            setTimeout(() => {
                                            resolve('done!');
                                            }, 500);

                                            // Pass your promise to the world
                                            return promise;
                                            }

                                            (async function run() {

                                            const result = await doSomethingAsync()
                                            .catch(err => console.error('rejected with', err));
                                            console.log(result);

                                            })();





                                            Edit:
                                            I have created an NPM package called flat-promise and the code is also available on GitHub.






                                            share|improve this answer



























                                              up vote
                                              0
                                              down vote













                                              I'm using a helper function to create what I call a "flat promise" -



                                              function flatPromise() {

                                              let resolve, reject;

                                              const promise = new Promise((res, rej) => {
                                              resolve = res;
                                              reject = rej;
                                              });

                                              return { promise, resolve, reject };
                                              }


                                              And I'm using it like so -



                                              function doSomethingAsync() {

                                              // Get your promise and callbacks
                                              const { resolve, reject, promise } = flatPromise();

                                              // Do something amazing...
                                              setTimeout(() => {
                                              resolve('done!');
                                              }, 500);

                                              // Pass your promise to the world
                                              return promise;

                                              }


                                              See full working example -






                                              function flatPromise() {

                                              let resolve, reject;

                                              const promise = new Promise((res, rej) => {
                                              resolve = res;
                                              reject = rej;
                                              });

                                              return { promise, resolve, reject };
                                              }

                                              function doSomethingAsync() {

                                              // Get your promise and callbacks
                                              const { resolve, reject, promise } = flatPromise();

                                              // Do something amazing...
                                              setTimeout(() => {
                                              resolve('done!');
                                              }, 500);

                                              // Pass your promise to the world
                                              return promise;
                                              }

                                              (async function run() {

                                              const result = await doSomethingAsync()
                                              .catch(err => console.error('rejected with', err));
                                              console.log(result);

                                              })();





                                              Edit:
                                              I have created an NPM package called flat-promise and the code is also available on GitHub.






                                              share|improve this answer

























                                                up vote
                                                0
                                                down vote










                                                up vote
                                                0
                                                down vote









                                                I'm using a helper function to create what I call a "flat promise" -



                                                function flatPromise() {

                                                let resolve, reject;

                                                const promise = new Promise((res, rej) => {
                                                resolve = res;
                                                reject = rej;
                                                });

                                                return { promise, resolve, reject };
                                                }


                                                And I'm using it like so -



                                                function doSomethingAsync() {

                                                // Get your promise and callbacks
                                                const { resolve, reject, promise } = flatPromise();

                                                // Do something amazing...
                                                setTimeout(() => {
                                                resolve('done!');
                                                }, 500);

                                                // Pass your promise to the world
                                                return promise;

                                                }


                                                See full working example -






                                                function flatPromise() {

                                                let resolve, reject;

                                                const promise = new Promise((res, rej) => {
                                                resolve = res;
                                                reject = rej;
                                                });

                                                return { promise, resolve, reject };
                                                }

                                                function doSomethingAsync() {

                                                // Get your promise and callbacks
                                                const { resolve, reject, promise } = flatPromise();

                                                // Do something amazing...
                                                setTimeout(() => {
                                                resolve('done!');
                                                }, 500);

                                                // Pass your promise to the world
                                                return promise;
                                                }

                                                (async function run() {

                                                const result = await doSomethingAsync()
                                                .catch(err => console.error('rejected with', err));
                                                console.log(result);

                                                })();





                                                Edit:
                                                I have created an NPM package called flat-promise and the code is also available on GitHub.






                                                share|improve this answer














                                                I'm using a helper function to create what I call a "flat promise" -



                                                function flatPromise() {

                                                let resolve, reject;

                                                const promise = new Promise((res, rej) => {
                                                resolve = res;
                                                reject = rej;
                                                });

                                                return { promise, resolve, reject };
                                                }


                                                And I'm using it like so -



                                                function doSomethingAsync() {

                                                // Get your promise and callbacks
                                                const { resolve, reject, promise } = flatPromise();

                                                // Do something amazing...
                                                setTimeout(() => {
                                                resolve('done!');
                                                }, 500);

                                                // Pass your promise to the world
                                                return promise;

                                                }


                                                See full working example -






                                                function flatPromise() {

                                                let resolve, reject;

                                                const promise = new Promise((res, rej) => {
                                                resolve = res;
                                                reject = rej;
                                                });

                                                return { promise, resolve, reject };
                                                }

                                                function doSomethingAsync() {

                                                // Get your promise and callbacks
                                                const { resolve, reject, promise } = flatPromise();

                                                // Do something amazing...
                                                setTimeout(() => {
                                                resolve('done!');
                                                }, 500);

                                                // Pass your promise to the world
                                                return promise;
                                                }

                                                (async function run() {

                                                const result = await doSomethingAsync()
                                                .catch(err => console.error('rejected with', err));
                                                console.log(result);

                                                })();





                                                Edit:
                                                I have created an NPM package called flat-promise and the code is also available on GitHub.






                                                function flatPromise() {

                                                let resolve, reject;

                                                const promise = new Promise((res, rej) => {
                                                resolve = res;
                                                reject = rej;
                                                });

                                                return { promise, resolve, reject };
                                                }

                                                function doSomethingAsync() {

                                                // Get your promise and callbacks
                                                const { resolve, reject, promise } = flatPromise();

                                                // Do something amazing...
                                                setTimeout(() => {
                                                resolve('done!');
                                                }, 500);

                                                // Pass your promise to the world
                                                return promise;
                                                }

                                                (async function run() {

                                                const result = await doSomethingAsync()
                                                .catch(err => console.error('rejected with', err));
                                                console.log(result);

                                                })();





                                                function flatPromise() {

                                                let resolve, reject;

                                                const promise = new Promise((res, rej) => {
                                                resolve = res;
                                                reject = rej;
                                                });

                                                return { promise, resolve, reject };
                                                }

                                                function doSomethingAsync() {

                                                // Get your promise and callbacks
                                                const { resolve, reject, promise } = flatPromise();

                                                // Do something amazing...
                                                setTimeout(() => {
                                                resolve('done!');
                                                }, 500);

                                                // Pass your promise to the world
                                                return promise;
                                                }

                                                (async function run() {

                                                const result = await doSomethingAsync()
                                                .catch(err => console.error('rejected with', err));
                                                console.log(result);

                                                })();






                                                share|improve this answer














                                                share|improve this answer



                                                share|improve this answer








                                                edited yesterday

























                                                answered Nov 19 at 11:36









                                                Arik

                                                2,02311213




                                                2,02311213






























                                                     

                                                    draft saved


                                                    draft discarded



















































                                                     


                                                    draft saved


                                                    draft discarded














                                                    StackExchange.ready(
                                                    function () {
                                                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f26150232%2fresolve-javascript-promise-outside-function-scope%23new-answer', 'question_page');
                                                    }
                                                    );

                                                    Post as a guest















                                                    Required, but never shown





















































                                                    Required, but never shown














                                                    Required, but never shown












                                                    Required, but never shown







                                                    Required, but never shown

































                                                    Required, but never shown














                                                    Required, but never shown












                                                    Required, but never shown







                                                    Required, but never shown







                                                    Popular posts from this blog

                                                    MongoDB - Not Authorized To Execute Command

                                                    How to fix TextFormField cause rebuild widget in Flutter

                                                    Npm cannot find a required file even through it is in the searched directory