return a promise of an ongoing asynchronous call





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







0















I'm trying to launch simultanuously many asynchrnous functions. Some of them make some http calls and I obviously don't want to make the same call multiple times. So, how can this be done using ES6 Promises and if not, what machanism would you recommend to deal with this kind of situations.



Example of the issue:



const func1 = () => async1();

const func2 = () => async2().then(async1);

return Promise.all([func1(), func2()]);


async1 and async2 are asynchronous functions returning Promises.
The issue is how to deal with three situations :




  • func1 and func2 launch async1 in the same time

  • func2 launches async1 while async1 is an ongoing asynchronous call in func2

  • async1 is launched by func2 after async1 has already been resolved by func1


The last situation is the only one I call deal with right now to prevent same calls from launching multiple times.










share|improve this question

























  • @charlietfl async1 will be called twice in the sample code

    – skyboyer
    Nov 23 '18 at 14:26











  • Why you don't just call func2 without then(async1)?

    – codtex
    Nov 23 '18 at 14:27











  • @codtex beacuse func1 and func2 are simplified in the example above and in real life they are functions that can be called alone and within Promise.all. So I need I guess some kind of incapsulation of those async functions to not be called when they already have been called or wait if another function is waiting a response..

    – mouad
    Nov 23 '18 at 14:30













  • Situation is oversimplified to point we need to ask too many questions. In particular what would differ in async1() if called in func1 or func2? You can cache the promise but not sure if it needs complex cache or very simple one

    – charlietfl
    Nov 23 '18 at 14:31








  • 1





    @charlietfl is right, but I get your point anyway. In my opinion is better to rethink your logic design and avoid calling one async function from other functions multiple times. Otherwise something else I suggest is to write a simple wrapper class of Promise and set a running property (for example), when working with this object you can always check this property before executing. I can write u a simple example if this conception is not clear

    – codtex
    Nov 23 '18 at 14:34


















0















I'm trying to launch simultanuously many asynchrnous functions. Some of them make some http calls and I obviously don't want to make the same call multiple times. So, how can this be done using ES6 Promises and if not, what machanism would you recommend to deal with this kind of situations.



Example of the issue:



const func1 = () => async1();

const func2 = () => async2().then(async1);

return Promise.all([func1(), func2()]);


async1 and async2 are asynchronous functions returning Promises.
The issue is how to deal with three situations :




  • func1 and func2 launch async1 in the same time

  • func2 launches async1 while async1 is an ongoing asynchronous call in func2

  • async1 is launched by func2 after async1 has already been resolved by func1


The last situation is the only one I call deal with right now to prevent same calls from launching multiple times.










share|improve this question

























  • @charlietfl async1 will be called twice in the sample code

    – skyboyer
    Nov 23 '18 at 14:26











  • Why you don't just call func2 without then(async1)?

    – codtex
    Nov 23 '18 at 14:27











  • @codtex beacuse func1 and func2 are simplified in the example above and in real life they are functions that can be called alone and within Promise.all. So I need I guess some kind of incapsulation of those async functions to not be called when they already have been called or wait if another function is waiting a response..

    – mouad
    Nov 23 '18 at 14:30













  • Situation is oversimplified to point we need to ask too many questions. In particular what would differ in async1() if called in func1 or func2? You can cache the promise but not sure if it needs complex cache or very simple one

    – charlietfl
    Nov 23 '18 at 14:31








  • 1





    @charlietfl is right, but I get your point anyway. In my opinion is better to rethink your logic design and avoid calling one async function from other functions multiple times. Otherwise something else I suggest is to write a simple wrapper class of Promise and set a running property (for example), when working with this object you can always check this property before executing. I can write u a simple example if this conception is not clear

    – codtex
    Nov 23 '18 at 14:34














0












0








0








I'm trying to launch simultanuously many asynchrnous functions. Some of them make some http calls and I obviously don't want to make the same call multiple times. So, how can this be done using ES6 Promises and if not, what machanism would you recommend to deal with this kind of situations.



Example of the issue:



const func1 = () => async1();

const func2 = () => async2().then(async1);

return Promise.all([func1(), func2()]);


async1 and async2 are asynchronous functions returning Promises.
The issue is how to deal with three situations :




  • func1 and func2 launch async1 in the same time

  • func2 launches async1 while async1 is an ongoing asynchronous call in func2

  • async1 is launched by func2 after async1 has already been resolved by func1


The last situation is the only one I call deal with right now to prevent same calls from launching multiple times.










share|improve this question
















I'm trying to launch simultanuously many asynchrnous functions. Some of them make some http calls and I obviously don't want to make the same call multiple times. So, how can this be done using ES6 Promises and if not, what machanism would you recommend to deal with this kind of situations.



Example of the issue:



const func1 = () => async1();

const func2 = () => async2().then(async1);

return Promise.all([func1(), func2()]);


async1 and async2 are asynchronous functions returning Promises.
The issue is how to deal with three situations :




  • func1 and func2 launch async1 in the same time

  • func2 launches async1 while async1 is an ongoing asynchronous call in func2

  • async1 is launched by func2 after async1 has already been resolved by func1


The last situation is the only one I call deal with right now to prevent same calls from launching multiple times.







javascript node.js asynchronous es6-promise






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 23 '18 at 14:21







mouad

















asked Nov 23 '18 at 14:15









mouadmouad

84110




84110













  • @charlietfl async1 will be called twice in the sample code

    – skyboyer
    Nov 23 '18 at 14:26











  • Why you don't just call func2 without then(async1)?

    – codtex
    Nov 23 '18 at 14:27











  • @codtex beacuse func1 and func2 are simplified in the example above and in real life they are functions that can be called alone and within Promise.all. So I need I guess some kind of incapsulation of those async functions to not be called when they already have been called or wait if another function is waiting a response..

    – mouad
    Nov 23 '18 at 14:30













  • Situation is oversimplified to point we need to ask too many questions. In particular what would differ in async1() if called in func1 or func2? You can cache the promise but not sure if it needs complex cache or very simple one

    – charlietfl
    Nov 23 '18 at 14:31








  • 1





    @charlietfl is right, but I get your point anyway. In my opinion is better to rethink your logic design and avoid calling one async function from other functions multiple times. Otherwise something else I suggest is to write a simple wrapper class of Promise and set a running property (for example), when working with this object you can always check this property before executing. I can write u a simple example if this conception is not clear

    – codtex
    Nov 23 '18 at 14:34



















  • @charlietfl async1 will be called twice in the sample code

    – skyboyer
    Nov 23 '18 at 14:26











  • Why you don't just call func2 without then(async1)?

    – codtex
    Nov 23 '18 at 14:27











  • @codtex beacuse func1 and func2 are simplified in the example above and in real life they are functions that can be called alone and within Promise.all. So I need I guess some kind of incapsulation of those async functions to not be called when they already have been called or wait if another function is waiting a response..

    – mouad
    Nov 23 '18 at 14:30













  • Situation is oversimplified to point we need to ask too many questions. In particular what would differ in async1() if called in func1 or func2? You can cache the promise but not sure if it needs complex cache or very simple one

    – charlietfl
    Nov 23 '18 at 14:31








  • 1





    @charlietfl is right, but I get your point anyway. In my opinion is better to rethink your logic design and avoid calling one async function from other functions multiple times. Otherwise something else I suggest is to write a simple wrapper class of Promise and set a running property (for example), when working with this object you can always check this property before executing. I can write u a simple example if this conception is not clear

    – codtex
    Nov 23 '18 at 14:34

















@charlietfl async1 will be called twice in the sample code

– skyboyer
Nov 23 '18 at 14:26





@charlietfl async1 will be called twice in the sample code

– skyboyer
Nov 23 '18 at 14:26













Why you don't just call func2 without then(async1)?

– codtex
Nov 23 '18 at 14:27





Why you don't just call func2 without then(async1)?

– codtex
Nov 23 '18 at 14:27













@codtex beacuse func1 and func2 are simplified in the example above and in real life they are functions that can be called alone and within Promise.all. So I need I guess some kind of incapsulation of those async functions to not be called when they already have been called or wait if another function is waiting a response..

– mouad
Nov 23 '18 at 14:30







@codtex beacuse func1 and func2 are simplified in the example above and in real life they are functions that can be called alone and within Promise.all. So I need I guess some kind of incapsulation of those async functions to not be called when they already have been called or wait if another function is waiting a response..

– mouad
Nov 23 '18 at 14:30















Situation is oversimplified to point we need to ask too many questions. In particular what would differ in async1() if called in func1 or func2? You can cache the promise but not sure if it needs complex cache or very simple one

– charlietfl
Nov 23 '18 at 14:31







Situation is oversimplified to point we need to ask too many questions. In particular what would differ in async1() if called in func1 or func2? You can cache the promise but not sure if it needs complex cache or very simple one

– charlietfl
Nov 23 '18 at 14:31






1




1





@charlietfl is right, but I get your point anyway. In my opinion is better to rethink your logic design and avoid calling one async function from other functions multiple times. Otherwise something else I suggest is to write a simple wrapper class of Promise and set a running property (for example), when working with this object you can always check this property before executing. I can write u a simple example if this conception is not clear

– codtex
Nov 23 '18 at 14:34





@charlietfl is right, but I get your point anyway. In my opinion is better to rethink your logic design and avoid calling one async function from other functions multiple times. Otherwise something else I suggest is to write a simple wrapper class of Promise and set a running property (for example), when working with this object you can always check this property before executing. I can write u a simple example if this conception is not clear

– codtex
Nov 23 '18 at 14:34












2 Answers
2






active

oldest

votes


















1














You can reuse a promise object any time so if you store a request promise the first time it gets called you can return the stored promise on subsequent calls and avoid making multiple requests to same resource






const async1 = (() => {
let promise;

return (arg) => {
console.log(arg, ' = ', promise ? 'Cached request' : 'New request');
promise = promise || new Promise((res) => setTimeout(res, 500));
return promise.then(()=>arg);
}

})()

Promise.all([async1(1),async1(2)]).then(res=>console.log(res))








share|improve this answer


























  • thanks ! this is exactly what I was looking for

    – mouad
    Nov 23 '18 at 15:32



















0














If I understand it right you want to ensure async1 in your example will not be called twice.



The easy and (quite low)-level of achieving that is memoization.



Say with lodash's _.memoize() it would be



const async1 = _.memoize(async1, () => 1)
// wrapping func1 and func2 is not actually required in this case
const func1 = _.memoize(() => async1());
const func2 = _.memoize(() => async2().then(async1));
return Promise.all([func1(), func2()]);


Beware since you are unable to transparently switch from memoized to _un_memoized implementations on fly.



[UPD] since memoization relies on arguments passed you may need to pass resolver callback. Say in your case async1 may either got zero arguments or something coming from previous promise(when used in .then). So arguments are different but since we know all arguments don't matter we can pass resolver that returns constant as a key(say, '1')






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',
    autoActivateHeartbeat: false,
    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%2f53448301%2freturn-a-promise-of-an-ongoing-asynchronous-call%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    You can reuse a promise object any time so if you store a request promise the first time it gets called you can return the stored promise on subsequent calls and avoid making multiple requests to same resource






    const async1 = (() => {
    let promise;

    return (arg) => {
    console.log(arg, ' = ', promise ? 'Cached request' : 'New request');
    promise = promise || new Promise((res) => setTimeout(res, 500));
    return promise.then(()=>arg);
    }

    })()

    Promise.all([async1(1),async1(2)]).then(res=>console.log(res))








    share|improve this answer


























    • thanks ! this is exactly what I was looking for

      – mouad
      Nov 23 '18 at 15:32
















    1














    You can reuse a promise object any time so if you store a request promise the first time it gets called you can return the stored promise on subsequent calls and avoid making multiple requests to same resource






    const async1 = (() => {
    let promise;

    return (arg) => {
    console.log(arg, ' = ', promise ? 'Cached request' : 'New request');
    promise = promise || new Promise((res) => setTimeout(res, 500));
    return promise.then(()=>arg);
    }

    })()

    Promise.all([async1(1),async1(2)]).then(res=>console.log(res))








    share|improve this answer


























    • thanks ! this is exactly what I was looking for

      – mouad
      Nov 23 '18 at 15:32














    1












    1








    1







    You can reuse a promise object any time so if you store a request promise the first time it gets called you can return the stored promise on subsequent calls and avoid making multiple requests to same resource






    const async1 = (() => {
    let promise;

    return (arg) => {
    console.log(arg, ' = ', promise ? 'Cached request' : 'New request');
    promise = promise || new Promise((res) => setTimeout(res, 500));
    return promise.then(()=>arg);
    }

    })()

    Promise.all([async1(1),async1(2)]).then(res=>console.log(res))








    share|improve this answer















    You can reuse a promise object any time so if you store a request promise the first time it gets called you can return the stored promise on subsequent calls and avoid making multiple requests to same resource






    const async1 = (() => {
    let promise;

    return (arg) => {
    console.log(arg, ' = ', promise ? 'Cached request' : 'New request');
    promise = promise || new Promise((res) => setTimeout(res, 500));
    return promise.then(()=>arg);
    }

    })()

    Promise.all([async1(1),async1(2)]).then(res=>console.log(res))








    const async1 = (() => {
    let promise;

    return (arg) => {
    console.log(arg, ' = ', promise ? 'Cached request' : 'New request');
    promise = promise || new Promise((res) => setTimeout(res, 500));
    return promise.then(()=>arg);
    }

    })()

    Promise.all([async1(1),async1(2)]).then(res=>console.log(res))





    const async1 = (() => {
    let promise;

    return (arg) => {
    console.log(arg, ' = ', promise ? 'Cached request' : 'New request');
    promise = promise || new Promise((res) => setTimeout(res, 500));
    return promise.then(()=>arg);
    }

    })()

    Promise.all([async1(1),async1(2)]).then(res=>console.log(res))






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 23 '18 at 15:18

























    answered Nov 23 '18 at 15:10









    charlietflcharlietfl

    141k1391125




    141k1391125













    • thanks ! this is exactly what I was looking for

      – mouad
      Nov 23 '18 at 15:32



















    • thanks ! this is exactly what I was looking for

      – mouad
      Nov 23 '18 at 15:32

















    thanks ! this is exactly what I was looking for

    – mouad
    Nov 23 '18 at 15:32





    thanks ! this is exactly what I was looking for

    – mouad
    Nov 23 '18 at 15:32













    0














    If I understand it right you want to ensure async1 in your example will not be called twice.



    The easy and (quite low)-level of achieving that is memoization.



    Say with lodash's _.memoize() it would be



    const async1 = _.memoize(async1, () => 1)
    // wrapping func1 and func2 is not actually required in this case
    const func1 = _.memoize(() => async1());
    const func2 = _.memoize(() => async2().then(async1));
    return Promise.all([func1(), func2()]);


    Beware since you are unable to transparently switch from memoized to _un_memoized implementations on fly.



    [UPD] since memoization relies on arguments passed you may need to pass resolver callback. Say in your case async1 may either got zero arguments or something coming from previous promise(when used in .then). So arguments are different but since we know all arguments don't matter we can pass resolver that returns constant as a key(say, '1')






    share|improve this answer






























      0














      If I understand it right you want to ensure async1 in your example will not be called twice.



      The easy and (quite low)-level of achieving that is memoization.



      Say with lodash's _.memoize() it would be



      const async1 = _.memoize(async1, () => 1)
      // wrapping func1 and func2 is not actually required in this case
      const func1 = _.memoize(() => async1());
      const func2 = _.memoize(() => async2().then(async1));
      return Promise.all([func1(), func2()]);


      Beware since you are unable to transparently switch from memoized to _un_memoized implementations on fly.



      [UPD] since memoization relies on arguments passed you may need to pass resolver callback. Say in your case async1 may either got zero arguments or something coming from previous promise(when used in .then). So arguments are different but since we know all arguments don't matter we can pass resolver that returns constant as a key(say, '1')






      share|improve this answer




























        0












        0








        0







        If I understand it right you want to ensure async1 in your example will not be called twice.



        The easy and (quite low)-level of achieving that is memoization.



        Say with lodash's _.memoize() it would be



        const async1 = _.memoize(async1, () => 1)
        // wrapping func1 and func2 is not actually required in this case
        const func1 = _.memoize(() => async1());
        const func2 = _.memoize(() => async2().then(async1));
        return Promise.all([func1(), func2()]);


        Beware since you are unable to transparently switch from memoized to _un_memoized implementations on fly.



        [UPD] since memoization relies on arguments passed you may need to pass resolver callback. Say in your case async1 may either got zero arguments or something coming from previous promise(when used in .then). So arguments are different but since we know all arguments don't matter we can pass resolver that returns constant as a key(say, '1')






        share|improve this answer















        If I understand it right you want to ensure async1 in your example will not be called twice.



        The easy and (quite low)-level of achieving that is memoization.



        Say with lodash's _.memoize() it would be



        const async1 = _.memoize(async1, () => 1)
        // wrapping func1 and func2 is not actually required in this case
        const func1 = _.memoize(() => async1());
        const func2 = _.memoize(() => async2().then(async1));
        return Promise.all([func1(), func2()]);


        Beware since you are unable to transparently switch from memoized to _un_memoized implementations on fly.



        [UPD] since memoization relies on arguments passed you may need to pass resolver callback. Say in your case async1 may either got zero arguments or something coming from previous promise(when used in .then). So arguments are different but since we know all arguments don't matter we can pass resolver that returns constant as a key(say, '1')







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 23 '18 at 14:40

























        answered Nov 23 '18 at 14:34









        skyboyerskyboyer

        4,23811333




        4,23811333






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53448301%2freturn-a-promise-of-an-ongoing-asynchronous-call%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







            這個網誌中的熱門文章

            Xamarin.form Move up view when keyboard appear

            Post-Redirect-Get with Spring WebFlux and Thymeleaf

            Anylogic : not able to use stopDelay()