使用Node.js

时间:2018-02-22 04:40:59

标签: javascript node.js asynchronous

我是Javascript的新手,我试图围绕Javascript的异步性概念。

我的目标是,

responseStr = httpPost(parameters)
// then store responseStr in DB

但是,我能做的Javascript是,

var callback = function(response) {
    var str = '';

    //another chunk of data has been recieved, so append it to `str`
    response.on('data', function(chunk) {
        str += chunk;
    });

    //the whole response has been recieved, so we just print it out here
    response.on('end', function() {
        console.log(str);
        });
    };

http.request(options, callback).end();

所以我从上面的代码中将http post请求的响应放到局部变量str中,但是我仍然无法想象如何将它传递回httpPost调用者responseStr < / p>

基本上,流程是,

  • 在我的httpPost函数中,我通过http.request
  • 发送了http请求
  • 并立即返回,
  • 某个时候某个时候,callback函数按位填充str个变量

但是当完成所有操作以便将其存储起来后,如何将其传递回httpPost来电者responseStr THX。

要点:

谢谢所有回答的人。我非常喜欢你所有的幽默感,赞美你们所有人。

PS。共享a piece of comment I read the other day,关于Javascript的异步性,

  

今天,我们将研究在node.js中异步执行相同任务的四种不同方法......:

     
      
  1. 并行使用回调函数
  2.   
  3. 依次使用回调函数
  4.   
  5. 同时使用promises
  6.   
  7. 依次使用承诺
  8.         

    这将帮助您确定针对您的特定情况使用哪种方法。这只是一个品味问题。如果你想知道哪种方法最好 - 绝对最好的方法 - 可能会切换到Golang

: - )

3 个答案:

答案 0 :(得分:2)

这很简单:你不能这样做。

这是您必须在JavaScript中处理的问题之一。在执行了推入事件循环的代码后,调用了回调函数,因此程序中的周围代码已经同步执行并且很快就会消失。

你应该深入了解事件循环以获得更好的感觉。

由于目前在您的代码中安排了一些内容,嵌套代码是处理此问题的最直接的方法。依赖于str的任何内容都会在str得到它的值的回调中被移动或调用。

另一种处理此问题的方法是找到支持基于promise的接口的包。这允许您的异步代码从嵌套结构转换,异步回调会强制您进入并展平代码。它甚至可以让你做一些像你在这里尝试做的事情。

const context = {};
doAsync()
  .then(function(result) {
    // Do something with result
    context.str = result;
    return doSomethingElseAsync();
  })
  .then(function(result) {
    // No more nesting, more readable, easier to reason about
    context.str2 = result;
    return doAsync3(context.str);
  });

答案 1 :(得分:1)

您尝试做的事情有几个问题。第一个问题是不可能从仅在将来可用的非阻塞函数返回值。不过不要担心,一旦时间旅行可能我们再也不用担心这个问题:)但在那之前,我们从哪里开始呢?我们可以采取一些措施来获得价值。

第一个(首选)解决方案是通过简单地移动使用值变为可用位置的值的所有功能来修改程序,例如:回调。例如,假设使用value的唯一功能是函数调用do_stuff_with(value)

// original program
var value = get_value('param', callback);
do_stuff_with(value);

// changes to
get_value('param', function (value) {
  do_stuff_with(value);
});

通常我从新程序员那里得到的反应是&#34;哦不!这意味着我需要改变我的整个程序!还有什么我们可以做的。我不想改变代码。它是完美的,现在是我家人的一部分。你是怪物!&#34; 我必须承认,这正是我提出同样的解决方案后的感受。您可能希望立即使用此问题的另一种解决方案,但它会极大地影响您的程序的性能。

第二个(可怕的,天真的,你很抱歉,不要这样做)成功返回函数调用值的解决方案要求您使用支持同步功能的方法。我只看到除了javascript以外的所有语言的同步代码,因为javascript是单线程的。 &#34; 亵渎神灵,这到底是什么意思?&#34;这意味着整个javascript程序需要暂停整个过程才能等待http请求完成。如果不打开新线程,则无法打开http请求。那不好吗?地狱,是的。这意味着整个用户界面将在http请求期间冻结。这意味着其他任务计划任务不会按时调用。你知道玩一直冻结的视频游戏是什么感觉。太可怕了。

&#34;但我没有想象力,我真的想写一个糟糕的节目。&#34; - 很好,只需修改程序即可使用实现同步功能的方法,而不是采用回调的异步方法。我不知道从哪里得到这个,因为我从来不需要它。

// replace this method
var value = get_str_async_method('param', callback);
console.log(value) // undefined

// use one that is synchronous
// a callback is not needed for this method
var value = get_str_sync_method('param');
console.log(value); // reponse

答案 2 :(得分:0)

如果您想在获取数据后存储所有数据,可以将其添加到嵌套函数中,如下面

var callback = function(response) {
var str = '';

//another chunk of data has been recieved, so append it to `str`
response.on('data', function(chunk) {
    str += chunk;
});

//the whole response has been recieved, so we just print it out here
response.on('end', function() {
    console.log(str);
    responseStr = httpPost(parameters); //this line should be added here 
    });
};
http.request(options, callback).end();