使用匿名函数时,堆栈顺序如何在javascript中运行? 我希望打印下面的代码:“先打电话给第二个电话打三次电话”,但是打印出来:“第二个电话叫第三个电话”。
[{"name":"Abbey Road","parent":"Beatles","children":[{"name":"Come Together","parent":"Abbey Road"}, {"name":"Something","parent":"Abbey Road"},{"name":"Maxwell","parent":"Abbey Road"}, {"name":"Oh! Darling","parent":"Abbey Road"}]}]
非常感谢任何帮助。 感谢
答案 0 :(得分:1)
不是匿名,而是异步会让你绊倒。你执行findTweets;执行T.get,最终将执行回调,并记录第二次调用&#39 ;;然后findTweets完成,所以你的脚本记录了第三次调用&#39 ;;最后,异步函数执行其回调,并记录首先调用'。
在调用异步函数之后,你不应该做任何取决于状态的事情"好像"异步功能已经完成,因为(正如你已经发现的那样)它经常不会有。
如果你有一个更复杂的情况,有些库可以帮助处理异步执行,例如async,或者你可以使用Promises。
答案 1 :(得分:1)
dmfay是正确的,异步的T.get()函数正在绊倒你。
查看MDN's write-up on the concurrency model
JavaScript从事件循环运行,从队列中处理消息。每条消息都与一个功能相关联。当堆栈具有容量时,将从队列中提取消息并进行处理。
每条消息都被处理完成,消息可以通过函数添加到队列中,包括将像T.get()函数一样异步处理的函数。在这种情况下,如果没有其他消息,则立即处理T.get(),但如果还有其他消息,例如console.log('third call'),则T.get()必须等待插入它消息进入堆栈,它必须等待它的回调完成才能调用console.log()。
function findTweets(params, num)
{
params = {
q: params,
count: num ,
language: 'en'
}
T.get('search/tweets', params, function(err, data, response) {
console.log("first call"); // 3. Ok, I'm done!
});
console.log("second call"); // 4. Finally!
}
findTweets("a str",1) //1. I can start now but can't finish until my callbacks do
console.log("third call"); // 2. Sweet! I can go right now.
如何按照预期的顺序执行这些操作?尝试承诺和回调。
为了看到这一点,我用一个包含get()方法的对象来创建twitterAPI函数。 stubbed()方法使用setTimeout()
欺骗延迟响应var twitterAPI = function () {
this.get = function (method, params, callback) {
setTimeout(function () {
callback()
}, 1000)
}
}
var T = new twitterAPI()
function findTweets (params, num, callback) {
params = {
q: params,
count: num,
language: 'en'
}
var p1 = new Promise(function(resolve, reject) {
T.get('search/tweets', params, function (err, data, response) {
resolve("first call") // first call resolved as a promise
})
})
p1.then(function(res) {
console.log(res) // log resolved promise
console.log("second call") // make second call
return callback() // return callback so third call can go
})
}
findTweets("a str", 1, function () {
console.log("third call") // Finally, third call is called
})
/*
first call
second call
third call
*/