在Javascript/Node.JS中调用匿名函数时的堆栈顺序

在Javascript/Node.JS中调用匿名函数时的堆栈顺序,javascript,node.js,stack,anonymous-function,Javascript,Node.js,Stack,Anonymous Function,使用匿名函数时,javascript中的堆栈顺序是如何工作的? 我希望打印以下代码:“first call second call third call”,但它会打印:“second call third call first call” 任何帮助都将不胜感激。 谢谢,绊倒你的不是匿名而是异步。您执行findTweets;它执行T.get,而T.get最终将执行回调,并记录“第二次调用”;然后findTweets完成,所以脚本记录“第三次调用”;最后,异步函数执行其回调,并记录“第一次调用” 在

使用匿名函数时,javascript中的堆栈顺序是如何工作的? 我希望打印以下代码:“first call second call third call”,但它会打印:“second call third call first call”

任何帮助都将不胜感激。
谢谢,绊倒你的不是匿名而是异步。您执行findTweets;它执行T.get,而T.get最终将执行回调,并记录“第二次调用”;然后findTweets完成,所以脚本记录“第三次调用”;最后,异步函数执行其回调,并记录“第一次调用”

在调用异步函数之后,不应该执行任何依赖于异步函数已完成状态的操作,因为(正如您所发现的)它通常不会完成


如果您有更复杂的情况,那么有一些库可以帮助处理异步执行,例如,或者您可以使用承诺。

让您绊倒的不是匿名性,而是异步性。您执行findTweets;它执行T.get,而T.get最终将执行回调,并记录“第二次调用”;然后findTweets完成,所以脚本记录“第三次调用”;最后,异步函数执行其回调,并记录“第一次调用”

在调用异步函数之后,不应该执行任何依赖于异步函数已完成状态的操作,因为(正如您所发现的)它通常不会完成


如果您遇到更复杂的情况,则可以使用一些库来帮助处理异步执行,例如,或者您可以使用Promissions。

dmfay正确地指出,异步T.get()函数会让您陷入困境

退房

JavaScript从事件循环运行,在事件循环中,消息从队列中处理。每条消息都与一个函数相关联。当堆栈具有容量时,将从队列中提取消息并进行处理

每个消息都被处理到完成,并且可以通过函数将消息添加到队列中,包括异步处理的函数,如T.get()函数。在这种情况下,如果没有其他消息,则会立即处理T.get(),但如果有其他消息,如console.log(“第三次调用”),则T.get()必须等待将其消息插入堆栈,并且必须等待回调完成后才能调用console.log()

函数findTweets(参数,num)
{
参数={
问:params,
计数:num,
语言:‘恩’
}
T.get('search/tweets',参数,函数(错误,数据,响应){
console.log(“第一次呼叫”);//3.好了,我做完了!
});
console.log(“第二次调用”);//4.终于!
}
findTweets(“一个str”,1)//1。我现在可以开始,但在回拨完成之前无法完成
console.log(“第三次调用”);//2.好极了!我现在可以走了。
如何才能让这些按您期望的顺序执行?尝试一个承诺和一个回电

为了看到这一点,我在twitterAPI函数中插入了一个包含get()方法的对象。stubbed get()方法使用setTimeout()伪造延迟响应

var twitterAPI=函数(){
this.get=函数(方法、参数、回调){
setTimeout(函数(){
回调函数()
}, 1000)
}
}
var T=new twitterAPI()
函数findTweets(参数、num、回调){
参数={
问:params,
计数:num,
语言:‘恩’
}
var p1=新承诺(功能(解决、拒绝){
T.get('search/tweets',参数,函数(错误,数据,响应){
resolve(“first call”)//作为承诺解决的第一个调用
})
})
p1.然后(功能(res){
console.log(res)//日志解析承诺
console.log(“第二次调用”)//进行第二次调用
return callback()//返回回调以便第三次调用可以继续
})
}
findTweets(“一个str”,1,函数(){
console.log(“第三次调用”)//最后,调用第三次调用
})
/*
第一个电话
第二次呼叫
第三次呼叫
*/

dmfay是正确的,异步T.get()函数会让您绊倒

退房

JavaScript从事件循环运行,在事件循环中,消息从队列中处理。每条消息都与一个函数相关联。当堆栈具有容量时,将从队列中提取消息并进行处理

每个消息都被处理到完成,并且可以通过函数将消息添加到队列中,包括异步处理的函数,如T.get()函数。在这种情况下,如果没有其他消息,则会立即处理T.get(),但如果有其他消息,如console.log(“第三次调用”),则T.get()必须等待将其消息插入堆栈,并且必须等待回调完成后才能调用console.log()

函数findTweets(参数,num)
{
参数={
问:params,
计数:num,
语言:‘恩’
}
T.get('search/tweets',参数,函数(错误,数据,响应){
console.log(“第一次呼叫”);//3.好了,我做完了!
});
console.log(“第二次调用”);//4.终于!
}
findTweets(“一个str”,1)//1。我现在可以开始,但在回拨完成之前无法完成
console.log(“第三次调用”);//2.好极了!我现在可以走了。
如何才能让这些按您期望的顺序执行?尝试一个承诺和一个回电

为了看到这一点,我在twitterAPI函数中插入了一个包含get()方法的对象。stubbed get()方法使用setTimeout()伪造延迟响应

var twitterAPI=函数(){
this.get=函数(方法、参数、回调){
setTimeout(函数(){
回调函数()
}, 1000)
}
}
var T=new twitterAPI()
函数findTweets(参数、num、回调){
参数={
问:params,
计数:num,
语言:‘恩’
}
var p1=新承诺(功能(解决、拒绝){
T.get('search/tweets',参数,
function findTweets(params, num)
{
     params = {
        q: params, 
        count: num ,
        language: 'en' 
     }
     T.get('search/tweets', params, function(err, data, response) {
         console.log("first call");
        });

     console.log("second call");
}
findTweets("a str",1)
console.log("third call");