Block function whilst waiting for response

六月ゝ 毕业季﹏ 提交于 2020-01-06 18:30:23

问题


I've got a NodeJS app i'm building (using Sails, but i guess that's irrelevant).

In my action, i have a number of requests to other services, datasources etc that i need to load up. However, because of the huge dependency on callbacks, my code is still executing long after the action has returned the HTML.

I must be missing something silly (or not quite getting the whole async thing) but how on earth do i stop my action from finishing until i have all my data ready to render the view?!

Cheers


回答1:


It's hard to tell exactly what the problem is but here is a guess. Assuming you have only one external call your code should look like this:

exports.myController = function(req, res) {

    longExternalCallOne(someparams, function(result) {

       // you must render your view inside the callback
       res.render('someview', {data: result});
    });

    // do not render here as you don't have the result yet. 

}

If you have more than two external calls your code will looks like this:

exports.myController = function(req, res) {

    longExternalCallOne(someparams, function(result1) {

       longExternalCallTwo(someparams, function(result2) {

         // you must render your view inside the most inner callback
         data = {some combination of result1 and result2};
         res.render('someview', {data: data });

       });

       // do not render here since you don't have result2 yet

    });

    // do not render here either as you don't have neither result1 nor result2 yet. 

}

As you can see, once you have more than one long running async call things start to get tricky. The code above is just for illustration purposes. If your second callback depends on the first one then you need something like it, but if longExternalCallOne and longExternalTwo are independent of each other you should be using a library like async to help parallelize the requests https://github.com/caolan/async




回答2:


I'd recommend getting very intimate with the async library

The docs are pretty good with that link above, but it basically boils down to a bunch of very handy calls like:

async.parallel([
    function(){ ... },
    function(){ ... }
], callback);

async.series([
    function(){ ... },
    function(){ ... }
]);

Node is inherently async, you need to learn to love it.




回答3:


You cannot stop your code. All you can do is check in all callbacks if everything is completed. If yes, go on with your code. If no, wait for the next callback and check again.




回答4:


You should not stop your code, but rather render your view in your other resources callback, so you wait for your resource to be reached before rendering. That's the common pattern in node.js.

If you have to wait for several callbacks to be called, you can check manually each time one is called if the others have been called too (with simple bool for example), and call your render function if yes. Or you can use async or other cool libraries which will make the task easier. Promises (with the bluebird library) could be an option too.




回答5:


I am guessing here, since there is no code example, but you might be running into something like this:

// let's say you have a function, you pass it an argument and callback
function myFunction(arg, callback) {
    // now you do something asynchronous with the argument
    doSomethingAsyncWithArg(arg, function() {
        // now you've got your arg formatted or whatever, render result
        res.render('someView', {arg: arg});
        // now do the callback
        callback();
        // but you also have stuff here!
        doSomethingElse();

    });
});

So, after you render, your code keeps running. How to prevent it? return from there.

return callback();

Now your inner function will stop processing after it calls callback.



来源:https://stackoverflow.com/questions/21833763/block-function-whilst-waiting-for-response

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!