node js callback - 订单总是一样吗?

时间:2016-09-09 23:06:06

标签: node.js callback

我编写了以下函数来进行回调。我一直认为回调的内容可能会在以后执行。在这种情况下,它不会......

 doesSomething(function(){
        console.log("1");
        var i = 0;
        while (i < 10000)
        {
            console.log("hello");
            i = i + 1;
        }
    });
 console.log("2");
 console.log("3");

无论我做什么,“2”和“3”总是在“1”和“千”之后出现。 像这样:

1
你好
你好
...
你好
你好
2
3

我认为它会做什么:
2
3
1
你好
你好
...
你好

即使这种行为使我的生活更简单,我也不明白为什么执行是程序性的。

你认为在某些情况下它可能会逆转吗?

3 个答案:

答案 0 :(得分:1)

从您提到的输出中,我可以说doesSomething中的代码中没有异步发生,可能看起来像这样:

   function doesSomething(callback) {
      <maybe some synchronous operations, e.g. no ajax or filesystem calls>

      callback();
  }

,所以调用函数的顺序将始终相同,就像您在上面发布的那样:

  1. doesSomething(回调)
  2. 的console.log(2)
  3. 的console.log(3)
  4. 如果你想要你提到的订单,你应该这样称呼它们:

    1. 的console.log(2)
    2. 的console.log(3)
    3. doesSomething(回调)
    4. 这不需要特别针对node.js做些什么。这是方法在JavaScript中执行的方式,因为它是单线程的,所以它是同步的。 当你调用方法doesSomething(callback)时,它会立即执行它,而不是其他任何东西,直到它完成

答案 1 :(得分:0)

这完全取决于doSomething()如何调用其回调。如果它同步调用回调(例如在它返回之前),那么该函数中的所有内容都将在doSomething()返回之前执行。如果它异步调用它(在它返回后的某个时间),那么你将得到一个不同的顺序。

因此,订单由您未在doSomething()中显示的代码确定。

根据您观察到的顺序,doSomething()必须同步调用其回调,因此它将按顺序执行,就像任何其他同步函数调用一样。

例如,以下是两种情况:

function doSomething(callback) {
    callback();
}

这会同步调用传递给它的回调,因此它将在doSomething()返回之前执行,因此它将在后面的代码之前执行。

这样的事情;

function doSomething(callback) {
    fs.writeFile('foo.txt', callback);
}

或:

function doSomething(callback) {
    setTimeout(callback, 50);
}

将在函数返回后的某个时间异步执行回调,您将看到与console.log()语句不同的执行顺序。

答案 2 :(得分:0)

javascript是单线程语言,但不是node.js运行时或浏览器。 node.js或浏览器提供的某些函数会触发将函数分配给要在单独线程中处理的任务队列

让我们举个例子,让dosomething async

这是你打印的同步代码,1 hello ...,2,3

function add_new_page($post) {

  // Credentials for basic authentication.
  $username = 'user';
  $password = 'password';

  // Request headers.
  $headers = array(
    'Authorization' => 'Basic ' . base64_encode( $username . ':' . $password ),
    'Content-Type' => 'application/json'
  );

  // Request URL.
  $url = "http://localhost/wp-json/wp/v2/pages";

  // Request body.
  $body = array(
    'slug' => $post->post_name,
    'status' => $post->post_status,
    'type' => $post->post_type,
    'title' => $post->post_title,
    'content' => $post->post_content,
    'excerpt' => $post->post_excerpt,
  );

  $body_json = json_encode($body);

  // Request arguments.
  $args = array(
    'method' => 'POST',
    'blocking'    => true,
    'headers'     => $headers,
    'cookies'     => array(),
    'body'        => $body_json,
  );

  // Fire request.
  $response = wp_remote_request($url, $args);

  // Handle response.
  if (is_wp_error($response)) {
    $error_message = $response->get_error_message();
    echo "Something went wrong: $error_message";
  } else {
    $response_body = json_decode(wp_remote_retrieve_body($response));
    // Display response body.
    echo '<pre>';
    print_r($response_body);
    echo '</pre>';
  }
  // Exit so we can read the response.
  exit();
}

这是异步代码,打印出3,2,1,hello ...

function doesSomething(callback) {
    callback();
}
doesSomething(function(){
    console.log("1");
    var i = 0;
    while (i < 3)
    {
        console.log("hello");
        i = i + 1;
    }
});
console.log("2");
console.log("3");

解释为什么第二个代码是异步的,你必须明白function doesSomething(callback) { setTimeout(callback, 0); } doesSomething(function(){ console.log("1"); var i = 0; while (i < 3) { console.log("hello"); i = i + 1; } }); console.log("2"); console.log("3"); 不是javascript的一部分,它是由node.js和浏览器提供的api。 setTimeout将回调函数放入要处理的队列中。此时,一个单独的线程运行setTimeout,当计时器结束时,它将回调放入回调队列,当调用堆栈清空时,回调队列中的任何内容都将被移动到调用堆栈并进行处理。

在节点中你可以使用process.nextTick(yourFunction);为了使它成为异步,这只是nodejs为你提供的另一个函数,它比使用setTimeout更好(我不会在这里讨论)你可以签出https://howtonode.org/understanding-process-next-tick以了解有关process.nextTick的更多信息

了解更多详情,请观看此视频https://youtu.be/8aGhZQkoFbQ?t=19m25s