2017-09-21 6 views
1

3つの非同期関数a、b、cがあるとします。それぞれ1分で実行し、終了後にコールバックを呼び出します(最初の引数で渡されます)。あなたはノードを伝えたかった場合は「実行を開始し、その後、終了後にBを実行し、Bが終了した後にCを実行して」それは次のようになります。は、これら2つの非同期コールバックが同じものを書いていますか?

コード例:

a(function() { 
    b(function() { 
    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() 
    }) 
}) 

a(b(c)) 

誰かが私に2つの例を与えました

は、しかし、私はまだ混乱して感じは、いくつかの説明が必要:D

+0

コールバックの代わりに約束を使用するのが最適な解決策です。 – alexmac

答えて

2

欲しかったものではありません

。引数として関数を渡すと、次のようになります。

function a() {} 
function b() {} 

... 

a(b) 

に相当します。ただし

function a() {} 

... 

a(function() {...}) 

、あなたがする機能を渡していないa(b(c))が、呼び出しの結果を言うときb(c)。その線路の等価です:

let partialResult = b(c); 
a(partialResult); 

最初の部分は、あなたが関数の引数c、とbを呼び出して、非常に我々はすでに見てきたもののように見えます。ただし、両方の関数を引数としてaを呼び出してはいませんが、評価結果はb(c)です。

これはなぜ機能するのですか?

a(function(){ //work 
    b(function(){ 
    c() 
    }) 
}) 

ここでは、引数としての機能をaを呼び出している、そしてその機能はbcでもないですが、匿名の1、function() {...}、そしてそれは、関数宣言ではなく、呼び出しているので、それではないのでaまで実行されます。

したがって、aが実行された後、パラメータとして別の匿名関数を持つbを呼び出す匿名関数コールバックを実行します。同じことが繰り返されます。次に、bが終了すると、そのコールバックを呼び出し、cを呼び出します。 。。

コールバックとして無名関数を aを実行」に変換
a(function() { 
    b(c) 
}); 

a仕上げ、コールバックとしてcbを実行し、そのコールバックを実行

このコードは、これに等しいです

+0

素晴らしい答えです。わかった。ありがとう! – Tianqing

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

()関数のパラメータとしての機能を期待しています。しかしあなたがb(c)を通過していたからです。あなたはすでに関数を呼び出したので、関数bの戻り値を返します。すなわち機能ではない。あなたは、bの引数にcを束縛し、次に引数cをつけてこの関数をaに渡すことでそれを行うことができます。 aは関数を受け取り、bは関数を受け取ります。

+0

後者の理由について説明しますか?ありがとう:D。 a(function(){// work } }) – Tianqing

+2

後者は、各関数が関数が引数として期待しているために機能します。最初の例では関数b()が呼び出され、非関数値が返されてから – marvel308

1

a(b(c))を呼び出すということは、b(c)の結果でaを呼び出すことを意味します。

b(c)を呼び出すと、結果がcであるbを呼び出すことを意味します。

これで、cを評価してbにパラメータとして渡し、次にb(c)を評価してaにパラメータとして渡します。あなたは重要な概念は、関数オブジェクトと呼び出しの間で差別化され

+0

に渡されたため、最初の例ではそうではありませんでした。後者の仕組みはどうですか? a(function(){// work b(function(){ c() } }) – Tianqing

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()   
     }) 
    }) 
関連する問題