我一直对此感到好奇,并且从未找到令人信服的答案。也许你们可以帮忙清理它。
请考虑以下情况:
案例1:
var toAddress = '';
if(j==1)
{
toAddress="abc@mydomain.com";
}
else
{
toAddress="xyz@mydomain.com";
}
sendAlertEmail(toAddress);
问题:我可以确定,当调用sendAlertEmail()函数时,我将填充“toAddress”吗?
答案/澄清非常感谢!
答案 0 :(得分:2)
对于您提供的示例代码:
var toAddress = '';
if(j==1)
{
toAddress="abc@mydomain.com";
}
else
{
toAddress="xyz@mydomain.com";
}
sendAlertEmail(toAddress);
你绝对可以肯定它是严格顺序的。也就是说toAddress
的值为"abc@mydomain.com"
或"xyz@mydomain.com"
。
但是,对于以下代码:
var toAddress = '';
doSomething(function(){
if(j==1)
{
toAddress="abc@mydomain.com";
}
else
{
toAddress="xyz@mydomain.com";
}
});
sendAlertEmail(toAddress);
那么它取决于函数doSomething
是否是异步的。找到的最佳位置是文档。第二个是查看实施情况。
如果doSomething
不是异步的,那么代码执行基本上是顺序的,您肯定可以确定toAddress
已正确填充。
但是,如果doSomething
是异步的,那么通常可以确定代码执行非顺序。因为这是异步函数的基本行为之一 - 它们会立即返回并执行稍后传递给它们的函数。
并非所有在函数上运行的函数都是异步的。同步函数的一个示例是数组的forEach
方法。但是所有异步函数都接受函数作为参数。那是因为它是在异步操作结束时执行某些代码的唯一方法。因此,每当您看到函数将函数作为参数时,您应该检查它是否是异步的。
答案 1 :(得分:0)
Node.js是单线程的(或者至少是JS执行)因此,由于所有上述代码都是同步的并且在同一个tick中排列,所以它们将按顺序运行,因此必须填充toAddress。
一旦引入异步函数,事情就变得复杂了。在异步情况下,变量可以在行之间切换,因为它们之间会出现滴答声。
为了澄清每个滴答过程中的代码,只需从执行的顶部到底部进行评估。在第一个滴答期间,执行范围是整个文件,但之后是回调和处理程序。
答案 2 :(得分:0)
您编写的代码非常简单,可以指出异步行为。看看这段代码:
var toAddress = 'abc@mydomain.com';
if(j==1)
{ func1(toAddress); }
else
{ func2(toAddress); }
sendAlertEmail(toAddress);
无法保证只有在执行了func1或func2(if else条件)后才会执行sendAlertEmail。在节点函数中,在调用它们时立即返回并执行下一个调用的函数。如果要确保它们按顺序执行使用回调或使用像async这样的库。