Understanding difference in two async code snippets












1















I was trying to get my hands dirty on advanced NodeJS concepts by Stephen Grinder.



Trying to teach the mere basics of redis, Stephen did something like this



app.get('/api/blogs', requireLogin, async (req, res) => {

//This time we are setting
const redis = require('redis')
const redisURL = 'redis://127.0.0.1:6379';
const client = redis.createClient(redisURL);
const util = require('util')
client.get = util.promisify(client.get)
//We are checking if we have ever fetched any blogs related to the user with req.user.id
const cachedBlog = await client.get(req.user.id)
//if we have stored list of blogs, we will return those
if (cachedBlog) {
console.log(cachedBlog)
console.log("Serving from Cache")
return res.send(JSON.parse(cachedBlogs))
} //this is JSONIFIED as well so we need to convert it into list of arrays

console.log("serving from Mongoose")
//if no cache exsist
const blogs = await Blog.find({_user: req.user.id})
//blogs here is an object so we would need to stringfy it
res.send(blogs);
client.set(req.user.id, JSON.stringify(blogs))

})


And it works without any error but in last two lines, if we change the order



 client.set(req.user.id, JSON.stringify(blogs))
res.send(blogs);


it does not display my blog.



Since inside the API, I am considering both of them to run asynchronously, I thought order won't matter.



Can anyone tell me what am I missing or unable to comprehend?










share|improve this question

























  • so not exception of any kind?

    – Tzomas
    Nov 16 '18 at 9:19











  • And by display what do you mean? from res.send or in the next call the console.log?

    – Tzomas
    Nov 16 '18 at 9:29











  • @Tzomas from res.send

    – NoobieSatan
    Nov 16 '18 at 9:35
















1















I was trying to get my hands dirty on advanced NodeJS concepts by Stephen Grinder.



Trying to teach the mere basics of redis, Stephen did something like this



app.get('/api/blogs', requireLogin, async (req, res) => {

//This time we are setting
const redis = require('redis')
const redisURL = 'redis://127.0.0.1:6379';
const client = redis.createClient(redisURL);
const util = require('util')
client.get = util.promisify(client.get)
//We are checking if we have ever fetched any blogs related to the user with req.user.id
const cachedBlog = await client.get(req.user.id)
//if we have stored list of blogs, we will return those
if (cachedBlog) {
console.log(cachedBlog)
console.log("Serving from Cache")
return res.send(JSON.parse(cachedBlogs))
} //this is JSONIFIED as well so we need to convert it into list of arrays

console.log("serving from Mongoose")
//if no cache exsist
const blogs = await Blog.find({_user: req.user.id})
//blogs here is an object so we would need to stringfy it
res.send(blogs);
client.set(req.user.id, JSON.stringify(blogs))

})


And it works without any error but in last two lines, if we change the order



 client.set(req.user.id, JSON.stringify(blogs))
res.send(blogs);


it does not display my blog.



Since inside the API, I am considering both of them to run asynchronously, I thought order won't matter.



Can anyone tell me what am I missing or unable to comprehend?










share|improve this question

























  • so not exception of any kind?

    – Tzomas
    Nov 16 '18 at 9:19











  • And by display what do you mean? from res.send or in the next call the console.log?

    – Tzomas
    Nov 16 '18 at 9:29











  • @Tzomas from res.send

    – NoobieSatan
    Nov 16 '18 at 9:35














1












1








1








I was trying to get my hands dirty on advanced NodeJS concepts by Stephen Grinder.



Trying to teach the mere basics of redis, Stephen did something like this



app.get('/api/blogs', requireLogin, async (req, res) => {

//This time we are setting
const redis = require('redis')
const redisURL = 'redis://127.0.0.1:6379';
const client = redis.createClient(redisURL);
const util = require('util')
client.get = util.promisify(client.get)
//We are checking if we have ever fetched any blogs related to the user with req.user.id
const cachedBlog = await client.get(req.user.id)
//if we have stored list of blogs, we will return those
if (cachedBlog) {
console.log(cachedBlog)
console.log("Serving from Cache")
return res.send(JSON.parse(cachedBlogs))
} //this is JSONIFIED as well so we need to convert it into list of arrays

console.log("serving from Mongoose")
//if no cache exsist
const blogs = await Blog.find({_user: req.user.id})
//blogs here is an object so we would need to stringfy it
res.send(blogs);
client.set(req.user.id, JSON.stringify(blogs))

})


And it works without any error but in last two lines, if we change the order



 client.set(req.user.id, JSON.stringify(blogs))
res.send(blogs);


it does not display my blog.



Since inside the API, I am considering both of them to run asynchronously, I thought order won't matter.



Can anyone tell me what am I missing or unable to comprehend?










share|improve this question
















I was trying to get my hands dirty on advanced NodeJS concepts by Stephen Grinder.



Trying to teach the mere basics of redis, Stephen did something like this



app.get('/api/blogs', requireLogin, async (req, res) => {

//This time we are setting
const redis = require('redis')
const redisURL = 'redis://127.0.0.1:6379';
const client = redis.createClient(redisURL);
const util = require('util')
client.get = util.promisify(client.get)
//We are checking if we have ever fetched any blogs related to the user with req.user.id
const cachedBlog = await client.get(req.user.id)
//if we have stored list of blogs, we will return those
if (cachedBlog) {
console.log(cachedBlog)
console.log("Serving from Cache")
return res.send(JSON.parse(cachedBlogs))
} //this is JSONIFIED as well so we need to convert it into list of arrays

console.log("serving from Mongoose")
//if no cache exsist
const blogs = await Blog.find({_user: req.user.id})
//blogs here is an object so we would need to stringfy it
res.send(blogs);
client.set(req.user.id, JSON.stringify(blogs))

})


And it works without any error but in last two lines, if we change the order



 client.set(req.user.id, JSON.stringify(blogs))
res.send(blogs);


it does not display my blog.



Since inside the API, I am considering both of them to run asynchronously, I thought order won't matter.



Can anyone tell me what am I missing or unable to comprehend?







node.js asynchronous redis






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 16 '18 at 9:16







NoobieSatan

















asked Nov 13 '18 at 20:41









NoobieSatanNoobieSatan

1,141527




1,141527













  • so not exception of any kind?

    – Tzomas
    Nov 16 '18 at 9:19











  • And by display what do you mean? from res.send or in the next call the console.log?

    – Tzomas
    Nov 16 '18 at 9:29











  • @Tzomas from res.send

    – NoobieSatan
    Nov 16 '18 at 9:35



















  • so not exception of any kind?

    – Tzomas
    Nov 16 '18 at 9:19











  • And by display what do you mean? from res.send or in the next call the console.log?

    – Tzomas
    Nov 16 '18 at 9:29











  • @Tzomas from res.send

    – NoobieSatan
    Nov 16 '18 at 9:35

















so not exception of any kind?

– Tzomas
Nov 16 '18 at 9:19





so not exception of any kind?

– Tzomas
Nov 16 '18 at 9:19













And by display what do you mean? from res.send or in the next call the console.log?

– Tzomas
Nov 16 '18 at 9:29





And by display what do you mean? from res.send or in the next call the console.log?

– Tzomas
Nov 16 '18 at 9:29













@Tzomas from res.send

– NoobieSatan
Nov 16 '18 at 9:35





@Tzomas from res.send

– NoobieSatan
Nov 16 '18 at 9:35












3 Answers
3






active

oldest

votes


















1





+50









Since OP asks to understand the difference, not fix the code:



express runs the request handler function and catches synchronous errors (they become http500 errors). It doesn't do anything with the promise returned from the async function and doesn't use await internally, so you don't get error handling for async functions for free. All asynchronous errors need to be caught inside and passed to the next callback or handled in your code by sending an appropriate status code and error body.



When an error occurs, JS stops and doesn't execute any more lines in the function. So if an error is thrown from client.set placed before res.send, the line with send won't run and no response is sent. The browser should continue waiting for the response until timeout.



The other way around - you send response before the error, so you get the page, but the response doesn't end (I'd assume the connection remains open as if the backend was going to send more) but ever since early versions of Firefox browsers start rendering HTML as it's downloaded, so you see a page even though the browser is still waiting for the response to finish.






share|improve this answer































    1














    The order of these two lines doesn't matter but that res.send isn't called in case client.set goes first means that there's an error. If an error occurs in async function, this may result in UnhandledPromiseRejectionWarning warning that will be visible in console.



    There are several problems with this snippet.



    That the error occurs even when though client.set is asynchronous suggests that client.set causes synchronous error which wasn't caught.



    client.set wasn't promisified but it should for correct control flow. That it wasn't provided with callback argument could be a reason why it caused an error.



    As explained in this answer, Express doesn't support promises, all rejections should be explicitly handled for proper error handling.



    All common code like require goes outside middleware function. It should be:



    const redis = require('redis')
    const redisURL = 'redis://127.0.0.1:6379';
    const client = redis.createClient(redisURL);
    const util = require('util')
    client.get = util.promisify(client.get)
    client.set = util.promisify(client.set)

    app.get('/api/blogs', requireLogin, async (req, res, next) => {
    try {
    const cachedBlog = await client.get(req.user.id)

    if (cachedBlog) {
    return res.send(JSON.parse(cachedBlogs))
    }

    const blogs = await Blog.find({_user: req.user.id});
    await client.set(req.user.id, JSON.stringify(blogs));
    res.send(blogs);
    } catch (err) {
    next(err);
    }
    })


    Most popular libraries have promise counterparts that allow to skip boilerplate promisification code, this applies to redis as well.






    share|improve this answer































      1














      The two task will runs asynchronously but the order of execution matters.



      client.set(req.user.id, JSON.stringify(blogs)) execution starts first, but as you are not using await, the promise will not be resolved but execution has already started.
      After that res.send() will execute.



      You are not getting the response implies that there is some error in the execution of client.set(req.user.id, JSON.stringify(blogs)).



      Use Try catch block to trace this error (as mentioned in other answers).



      You can also add these lines in your code to catch other "unhandledRejection" or "uncaughtException" error (if any).



      process.on('unhandledRejection', (err) => {
      logger.error('An unhandledRejection error occurred!');
      logger.error(err.stack)
      });
      process.on('uncaughtException', function (err) {
      logger.error('An uncaught error occurred!');
      logger.error(err.stack);
      });





      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%2f53289176%2funderstanding-difference-in-two-async-code-snippets%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        3 Answers
        3






        active

        oldest

        votes








        3 Answers
        3






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        1





        +50









        Since OP asks to understand the difference, not fix the code:



        express runs the request handler function and catches synchronous errors (they become http500 errors). It doesn't do anything with the promise returned from the async function and doesn't use await internally, so you don't get error handling for async functions for free. All asynchronous errors need to be caught inside and passed to the next callback or handled in your code by sending an appropriate status code and error body.



        When an error occurs, JS stops and doesn't execute any more lines in the function. So if an error is thrown from client.set placed before res.send, the line with send won't run and no response is sent. The browser should continue waiting for the response until timeout.



        The other way around - you send response before the error, so you get the page, but the response doesn't end (I'd assume the connection remains open as if the backend was going to send more) but ever since early versions of Firefox browsers start rendering HTML as it's downloaded, so you see a page even though the browser is still waiting for the response to finish.






        share|improve this answer




























          1





          +50









          Since OP asks to understand the difference, not fix the code:



          express runs the request handler function and catches synchronous errors (they become http500 errors). It doesn't do anything with the promise returned from the async function and doesn't use await internally, so you don't get error handling for async functions for free. All asynchronous errors need to be caught inside and passed to the next callback or handled in your code by sending an appropriate status code and error body.



          When an error occurs, JS stops and doesn't execute any more lines in the function. So if an error is thrown from client.set placed before res.send, the line with send won't run and no response is sent. The browser should continue waiting for the response until timeout.



          The other way around - you send response before the error, so you get the page, but the response doesn't end (I'd assume the connection remains open as if the backend was going to send more) but ever since early versions of Firefox browsers start rendering HTML as it's downloaded, so you see a page even though the browser is still waiting for the response to finish.






          share|improve this answer


























            1





            +50







            1





            +50



            1




            +50





            Since OP asks to understand the difference, not fix the code:



            express runs the request handler function and catches synchronous errors (they become http500 errors). It doesn't do anything with the promise returned from the async function and doesn't use await internally, so you don't get error handling for async functions for free. All asynchronous errors need to be caught inside and passed to the next callback or handled in your code by sending an appropriate status code and error body.



            When an error occurs, JS stops and doesn't execute any more lines in the function. So if an error is thrown from client.set placed before res.send, the line with send won't run and no response is sent. The browser should continue waiting for the response until timeout.



            The other way around - you send response before the error, so you get the page, but the response doesn't end (I'd assume the connection remains open as if the backend was going to send more) but ever since early versions of Firefox browsers start rendering HTML as it's downloaded, so you see a page even though the browser is still waiting for the response to finish.






            share|improve this answer













            Since OP asks to understand the difference, not fix the code:



            express runs the request handler function and catches synchronous errors (they become http500 errors). It doesn't do anything with the promise returned from the async function and doesn't use await internally, so you don't get error handling for async functions for free. All asynchronous errors need to be caught inside and passed to the next callback or handled in your code by sending an appropriate status code and error body.



            When an error occurs, JS stops and doesn't execute any more lines in the function. So if an error is thrown from client.set placed before res.send, the line with send won't run and no response is sent. The browser should continue waiting for the response until timeout.



            The other way around - you send response before the error, so you get the page, but the response doesn't end (I'd assume the connection remains open as if the backend was going to send more) but ever since early versions of Firefox browsers start rendering HTML as it's downloaded, so you see a page even though the browser is still waiting for the response to finish.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 20 '18 at 23:10









            naugturnaugtur

            15.1k559103




            15.1k559103

























                1














                The order of these two lines doesn't matter but that res.send isn't called in case client.set goes first means that there's an error. If an error occurs in async function, this may result in UnhandledPromiseRejectionWarning warning that will be visible in console.



                There are several problems with this snippet.



                That the error occurs even when though client.set is asynchronous suggests that client.set causes synchronous error which wasn't caught.



                client.set wasn't promisified but it should for correct control flow. That it wasn't provided with callback argument could be a reason why it caused an error.



                As explained in this answer, Express doesn't support promises, all rejections should be explicitly handled for proper error handling.



                All common code like require goes outside middleware function. It should be:



                const redis = require('redis')
                const redisURL = 'redis://127.0.0.1:6379';
                const client = redis.createClient(redisURL);
                const util = require('util')
                client.get = util.promisify(client.get)
                client.set = util.promisify(client.set)

                app.get('/api/blogs', requireLogin, async (req, res, next) => {
                try {
                const cachedBlog = await client.get(req.user.id)

                if (cachedBlog) {
                return res.send(JSON.parse(cachedBlogs))
                }

                const blogs = await Blog.find({_user: req.user.id});
                await client.set(req.user.id, JSON.stringify(blogs));
                res.send(blogs);
                } catch (err) {
                next(err);
                }
                })


                Most popular libraries have promise counterparts that allow to skip boilerplate promisification code, this applies to redis as well.






                share|improve this answer




























                  1














                  The order of these two lines doesn't matter but that res.send isn't called in case client.set goes first means that there's an error. If an error occurs in async function, this may result in UnhandledPromiseRejectionWarning warning that will be visible in console.



                  There are several problems with this snippet.



                  That the error occurs even when though client.set is asynchronous suggests that client.set causes synchronous error which wasn't caught.



                  client.set wasn't promisified but it should for correct control flow. That it wasn't provided with callback argument could be a reason why it caused an error.



                  As explained in this answer, Express doesn't support promises, all rejections should be explicitly handled for proper error handling.



                  All common code like require goes outside middleware function. It should be:



                  const redis = require('redis')
                  const redisURL = 'redis://127.0.0.1:6379';
                  const client = redis.createClient(redisURL);
                  const util = require('util')
                  client.get = util.promisify(client.get)
                  client.set = util.promisify(client.set)

                  app.get('/api/blogs', requireLogin, async (req, res, next) => {
                  try {
                  const cachedBlog = await client.get(req.user.id)

                  if (cachedBlog) {
                  return res.send(JSON.parse(cachedBlogs))
                  }

                  const blogs = await Blog.find({_user: req.user.id});
                  await client.set(req.user.id, JSON.stringify(blogs));
                  res.send(blogs);
                  } catch (err) {
                  next(err);
                  }
                  })


                  Most popular libraries have promise counterparts that allow to skip boilerplate promisification code, this applies to redis as well.






                  share|improve this answer


























                    1












                    1








                    1







                    The order of these two lines doesn't matter but that res.send isn't called in case client.set goes first means that there's an error. If an error occurs in async function, this may result in UnhandledPromiseRejectionWarning warning that will be visible in console.



                    There are several problems with this snippet.



                    That the error occurs even when though client.set is asynchronous suggests that client.set causes synchronous error which wasn't caught.



                    client.set wasn't promisified but it should for correct control flow. That it wasn't provided with callback argument could be a reason why it caused an error.



                    As explained in this answer, Express doesn't support promises, all rejections should be explicitly handled for proper error handling.



                    All common code like require goes outside middleware function. It should be:



                    const redis = require('redis')
                    const redisURL = 'redis://127.0.0.1:6379';
                    const client = redis.createClient(redisURL);
                    const util = require('util')
                    client.get = util.promisify(client.get)
                    client.set = util.promisify(client.set)

                    app.get('/api/blogs', requireLogin, async (req, res, next) => {
                    try {
                    const cachedBlog = await client.get(req.user.id)

                    if (cachedBlog) {
                    return res.send(JSON.parse(cachedBlogs))
                    }

                    const blogs = await Blog.find({_user: req.user.id});
                    await client.set(req.user.id, JSON.stringify(blogs));
                    res.send(blogs);
                    } catch (err) {
                    next(err);
                    }
                    })


                    Most popular libraries have promise counterparts that allow to skip boilerplate promisification code, this applies to redis as well.






                    share|improve this answer













                    The order of these two lines doesn't matter but that res.send isn't called in case client.set goes first means that there's an error. If an error occurs in async function, this may result in UnhandledPromiseRejectionWarning warning that will be visible in console.



                    There are several problems with this snippet.



                    That the error occurs even when though client.set is asynchronous suggests that client.set causes synchronous error which wasn't caught.



                    client.set wasn't promisified but it should for correct control flow. That it wasn't provided with callback argument could be a reason why it caused an error.



                    As explained in this answer, Express doesn't support promises, all rejections should be explicitly handled for proper error handling.



                    All common code like require goes outside middleware function. It should be:



                    const redis = require('redis')
                    const redisURL = 'redis://127.0.0.1:6379';
                    const client = redis.createClient(redisURL);
                    const util = require('util')
                    client.get = util.promisify(client.get)
                    client.set = util.promisify(client.set)

                    app.get('/api/blogs', requireLogin, async (req, res, next) => {
                    try {
                    const cachedBlog = await client.get(req.user.id)

                    if (cachedBlog) {
                    return res.send(JSON.parse(cachedBlogs))
                    }

                    const blogs = await Blog.find({_user: req.user.id});
                    await client.set(req.user.id, JSON.stringify(blogs));
                    res.send(blogs);
                    } catch (err) {
                    next(err);
                    }
                    })


                    Most popular libraries have promise counterparts that allow to skip boilerplate promisification code, this applies to redis as well.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Nov 17 '18 at 7:52









                    estusestus

                    68.7k21101216




                    68.7k21101216























                        1














                        The two task will runs asynchronously but the order of execution matters.



                        client.set(req.user.id, JSON.stringify(blogs)) execution starts first, but as you are not using await, the promise will not be resolved but execution has already started.
                        After that res.send() will execute.



                        You are not getting the response implies that there is some error in the execution of client.set(req.user.id, JSON.stringify(blogs)).



                        Use Try catch block to trace this error (as mentioned in other answers).



                        You can also add these lines in your code to catch other "unhandledRejection" or "uncaughtException" error (if any).



                        process.on('unhandledRejection', (err) => {
                        logger.error('An unhandledRejection error occurred!');
                        logger.error(err.stack)
                        });
                        process.on('uncaughtException', function (err) {
                        logger.error('An uncaught error occurred!');
                        logger.error(err.stack);
                        });





                        share|improve this answer




























                          1














                          The two task will runs asynchronously but the order of execution matters.



                          client.set(req.user.id, JSON.stringify(blogs)) execution starts first, but as you are not using await, the promise will not be resolved but execution has already started.
                          After that res.send() will execute.



                          You are not getting the response implies that there is some error in the execution of client.set(req.user.id, JSON.stringify(blogs)).



                          Use Try catch block to trace this error (as mentioned in other answers).



                          You can also add these lines in your code to catch other "unhandledRejection" or "uncaughtException" error (if any).



                          process.on('unhandledRejection', (err) => {
                          logger.error('An unhandledRejection error occurred!');
                          logger.error(err.stack)
                          });
                          process.on('uncaughtException', function (err) {
                          logger.error('An uncaught error occurred!');
                          logger.error(err.stack);
                          });





                          share|improve this answer


























                            1












                            1








                            1







                            The two task will runs asynchronously but the order of execution matters.



                            client.set(req.user.id, JSON.stringify(blogs)) execution starts first, but as you are not using await, the promise will not be resolved but execution has already started.
                            After that res.send() will execute.



                            You are not getting the response implies that there is some error in the execution of client.set(req.user.id, JSON.stringify(blogs)).



                            Use Try catch block to trace this error (as mentioned in other answers).



                            You can also add these lines in your code to catch other "unhandledRejection" or "uncaughtException" error (if any).



                            process.on('unhandledRejection', (err) => {
                            logger.error('An unhandledRejection error occurred!');
                            logger.error(err.stack)
                            });
                            process.on('uncaughtException', function (err) {
                            logger.error('An uncaught error occurred!');
                            logger.error(err.stack);
                            });





                            share|improve this answer













                            The two task will runs asynchronously but the order of execution matters.



                            client.set(req.user.id, JSON.stringify(blogs)) execution starts first, but as you are not using await, the promise will not be resolved but execution has already started.
                            After that res.send() will execute.



                            You are not getting the response implies that there is some error in the execution of client.set(req.user.id, JSON.stringify(blogs)).



                            Use Try catch block to trace this error (as mentioned in other answers).



                            You can also add these lines in your code to catch other "unhandledRejection" or "uncaughtException" error (if any).



                            process.on('unhandledRejection', (err) => {
                            logger.error('An unhandledRejection error occurred!');
                            logger.error(err.stack)
                            });
                            process.on('uncaughtException', function (err) {
                            logger.error('An uncaught error occurred!');
                            logger.error(err.stack);
                            });






                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Nov 22 '18 at 6:01









                            Mukul DevMukul Dev

                            664




                            664






























                                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%2f53289176%2funderstanding-difference-in-two-async-code-snippets%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()