2
function placeOrder(orderNo) {
console.log("Order is: " + orderNo);

setTimeout(deliver(orderNo),5000);
}

function deliver(orderNo) {
    console.log("Item is delivered with Order No.- " + orderNo);
}

placeOrder(1);
placeOrder(2);
placeOrder(3);
placeOrder(4);
placeOrder(5);
placeOrder(6);

上面的代码是一个nodejs代码,它的输出应该是:

order No:1
order No:2
order No:3
order No:4
order No:5
order No:6
Item is delivered with order No.- 1
Item is delivered with order No.- 2
Item is delivered with order No.- 3
Item is delivered with order No.- 4
Item is delivered with order No.- 5
Item is delivered with order No.- 6

但我得到这样的输出:

order No:1
Item is delivered with order No.- 1
order No:2
Item is delivered with order No.- 2
order No:3
Item is delivered with order No.- 3
order No:4
Item is delivered with order No.- 4
order No:5
Item is delivered with order No.- 5
order No:6
Item is delivered with order No.- 6

我在单线程和异步回调的概念中的某个地方出错了。请有人解释一下代码是如何工作的。

4

3 回答 3

2

代替:

setTimeout(deliver(orderNo),5000);
}

和:

setTimeout(function() {
    deliver(orderNo); 
}, 5000);

函数的第一个参数setTimeout是函数指针。在您的代码中,您传递的deliver(orderNo)调用结果只是一些void参数。现在你可以摆脱你的函数console.log内部了。placeOrder

于 2015-11-29T14:13:27.030 回答
2

您使用了错误setTimeout的签名定义

var timeoutID = window.setTimeout(func, [delay, param1, param2, ...]);
var timeoutID = window.setTimeout(code, [delay]);

因此,您的代码应该是:

setTimeout(function() {
  deliver(orderNo);
}, 5000);
于 2015-11-29T14:19:25.033 回答
0

tl;博士

这是一个语法问题。您将错误的参数类型传递给setTimeout.

改变这个:

setTimeout(deliver(orderNo),5000);

对此:

setTimeout(deliver, 5000, orderNo);

请注意,此语法在 IE 9 或更低版本中不起作用。

解释

如果您查看MDN 上的 setTimeout文档,您会看到第一个参数是 aFunctionString由 JavaScript 代码组成。在您的情况下,您正在尝试传入一个接受此语法的函数:

setTimeout(func, [delay, param1, param2, ...]);

param1, param2, ...您的函数的参数在哪里, func. 您所做的是传入函数返回的值,而不是函数本身

由于您正在传递一个值,setTimeout因此不会按预期执行。您仍然从中获得输出的原因deliver是因为它实际上是在运行时执行的,而不是由setTimeout. 这几乎和自己调用一样deliver

作为参数的函数

请记住,函数是JavaScript 中的一等公民,这意味着它们可以作为参数传递给函数。

奖金

您可以使用一些替代语法。

细绳

pokeybit评论中所述:

setTimeout("deliver("+orderNo+");",5000);

这允许您一次使用该函数及其参数。但是,由于字符串连接,这是一种更丑陋的语法。

匿名函数

将 setTimeout 与匿名函数一起使用:

setTimeout(function() {
  console.log("Item is delivered with Order No.- " + orderNo);
}, 5000);

这可以说是最常见和最安全的语法。

返回匿名函数的函数

您可以保留:

setTimeout(deliver(orderNo),5000);

如果您定义deliver为返回 a 的函数Function

function deliver(orderNo) {
  return function() {
    console.log("Item is delivered with Order No.- " + orderNo);
  }
}

由于这个值返回一个函数,它是正确的类型setTimeout

于 2015-11-29T14:59:36.407 回答