想象一下,你有3个异步函数a,b和c。每个运行需要1分钟才能运行,完成后会调用一个回调(在第一个参数中传递)。如果你想告诉节点'开始运行a,那么在完成后运行b,然后在b完成之后运行c'它看起来像这样:
示例代码:
a(function() {
b(function() {
c()
})
})
如果我像这样写,那会是一样的吗?
a(b(c))
有人给了我两个例子:
function a(func){
setTimeout(function(){
console.log('a');
func()
}, 1000)
}
function b(func){
setTimeout(function(){
console.log('b')
func()
}, 1000)
}
function c(){
setTimeout(function(){
console.log('c')
}, 1000)
}
a(b(c)) //get error
a(function(){ //work
b(function(){
c()
})
})
但我仍感到困惑,需要一些解释:D
答案 0 :(得分:2)
关键概念是区分功能对象和调用。将函数作为参数传递将如下所示:
function a() {}
function b() {}
...
a(b)
相当于:
function a() {}
...
a(function() {...})
但是,当您说a(b(c))
时,您没有将函数传递给a,而是调用b(c)
的结果。该行的等价物是:
let partialResult = b(c);
a(partialResult);
第一部分看起来非常像我们已经看到的,你使用参数b
调用c
,这是一个函数。但是,您不要将a
两个函数作为参数调用,而是使用评估结果b(c)
。
那么,为什么这有用呢?
a(function(){ //work
b(function(){
c()
})
})
因为在这里你用一个函数作为参数调用a
,并且该函数既不是b
也不是c
,而是一个匿名的function() {...}
,那就是函数声明,而不是调用,因此在a
这样说之前不会执行。
因此,a
被执行,然后它运行其回调,即匿名函数,它使用另一个匿名函数作为参数调用b
。同样的重复。然后,当b
完成后,它会调用其回调,然后调用c
。
该代码与此相同:
a(function() {
b(c)
});
转换为“使用匿名函数执行a
作为回调。当a
完成后,运行其回调,其中b
以c
作为回调运行。
答案 1 :(得分:1)
调用a(b(c))表示你使用b(c)的结果调用a。
调用b(c)表示您使用c。
的结果调用b所以你现在正在评估c作为参数传递给b,然后评估b(c)作为参数传递给a。
这不是你想要的
答案 2 :(得分:1)
[1] typeof(c) # Function
[2] b(c) # works because, b expects a function and gets one.
[3] typeof(c()) # undefined
[4] b(c()) # Fails because c doesn't return a function.
[5] b(function(c())) # Works because b expects a function and gets one
[6] typeof(b(c)) # undefined
[7] a(b(c)) # => a(undefined) => error
[8] typeof(function(){c()}) # function
[8] a(function() { # a expects a function and gets one
b(function() { # b expects a function and gets one
c()
})
})
答案 3 :(得分:0)
这对你有用
function a(func){
setTimeout(function(){
console.log('a');
func()
}, 1000)
}
function b(func){
setTimeout(function(){
console.log('b')
func()
}, 1000)
}
function c(){
setTimeout(function(){
console.log('c')
}, 1000)
}
a(b.bind(null, c)) //get error

function a()期望函数作为参数。但既然你通过了b(c)。您已经调用了函数,因此将返回函数b的返回值。即不是一种功能。你可以通过将c绑定到b的参数然后将带有参数c的函数传递给a来实现。所以a会收到一个函数,b会收到一个函数