2017-10-15 147 views
1

下面是一個我稍微困惑的問題的例子。瞭解JavaScript回調和正式參數

函數調用函數二,並傳遞一個具有正式參數的回調函數。

我的回答:

function one(){ 
function two(callback) 
{callback (param1, param2)} 
} 

請糾正,如果這是錯誤的

問題:

a)在函數調用回調?

函數的兩個調用回調函數

B)的功能提供回調的實際參數?

不確定

三)爲什麼要給一個回調的參數?

不確定

d)什麼是你放棄時,你有沒有提供一個回調的「異步」呼叫?

不確定

E)的異步調用被調用函數永遠包含同步調用?

不確定

+2

要更多的混亂添加到您的混亂,其中一個問題是不正確的闡述:*「哪個函數提供的回調的實際參數?」 *無:一個不提供參數,一個提供**參數**。 –

+1

在你的例子中'one'是**不**調用'two'。針對你的問題:a)正確的,b)不能說,因爲它沒有在代碼中顯示出來。c)因爲你可以在異步函數2之後執行代碼,並且你可以確定在兩個完成時調用它, d)動態的,e)確定它可以 –

+0

這些作業問題? – Tomalak

回答

1

解剖第一

的JavaScript可能會造成混淆,因爲有一個variety of ways to express functions - 對於所有意圖和目的,該功能下,可以認爲是相同的

// named function 
function myfunc (param1, param2) { 
    return returnValue 
} 

// function literal syntax 
const myfunc = function (param1, param2) { 
    return returnValue 
} 

// arrow function with explicit return (note { ... }) 
const myfunc = (param1, param2) => { 
    return returnValue 
} 

// arrow function with implicit return 
const myfunc = (param1, param2) => returnValue 

上面可以見函數有參數 - 在下面,你會看到函數個呼叫有參數

// call myfunc with 0 arguments 
myfunc() 

// call myfunc with 1 argument 
myfunc (arg1) 

// call myfunc with 2 arguments 
myfunc (arg1, arg2) 

他們只是起到

一)哪個函數調用回調功能?

因此,無論我們看到參數提供的功能,我們知道我們有呼叫處理 - 回答一個,只是看看,看看呼叫的封閉功能

function someFunc (param1, param2) { 
    // do something 
    const result = param1 * 2 

    // param2 called with result 
    param2 (result) 
} 

嘿看,param2 (result)是一個功能致電。我們期待它的函數看到someFunc是把它稱爲

B)哪個函數提供的回調函數的實際參數的一個?

那聽起來很愚蠢嗎?這就像問「Bobby的名字屬於誰?」 Bobby,當然。你可能意味着要問,這些功能提供了參數 - 在這種情況下,這個問題的答案將是someFunc - 它提供result參數

C)爲什麼要給一個回調函數的參數?

這瞬間只要我們停止調用函數回答了「回調」 - 回調是功能,而不是周圍的其他方式。我們給函數的參數,這樣我們就可以影響功能的行爲

d)什麼是你放棄當你有一個 N「異步」電話無需提供回調功能?

不要擔心異步與同步函數調用;有函數調用。函數調用發生在不同的時間,但在某些時候,調用將使用提供的參數來計算函數的主體並返回結果; undefined或以其他方式

在大多數情況下,「放棄」做任何事情,結果有用的能力 - 看看我們的功能再次:如果我們不提供param2result只是處於閒置

function someFunc (param1, param2) { 
    // do something 
    const result = param1 * 2 

    // param2 called with result 
    param2 (result) 
} 

但當然並非總是如此。要理解爲什麼,我們必須首先解決您的壽

d)問題什麼是你放棄時,你有沒有提供一個參數一個電話?

一種愚蠢的問題吧?但它是回調功能沒有什麼不同 - 他們只是普通的價值觀像別的

下面我們someFunc與天真名爲callback函數參數 - someFunc產生一個「有效」的結果有或沒有指定的回調 - 這樣爲d答案是:你放棄了什麼,明確

function someFunc (x, callback) { 
 
    if (callback) 
 
    return callback (x * 10) 
 
    else 
 
    return x * 2 
 
} 
 

 
// with the callback 
 
someFunc (5, console.log) // 50 
 

 
// without 
 
console.log (someFunc (5)) // 10

e) n異步調用中的被調用函數是否可以包含同步調用?

是的,函數可以調用其他函數。 JavaScript中的「同步」和「異步」這個想法歷史上是一種心理構造,因此很多人對此有不同的看法。要添加到這一點,JS的較新版本有一個async的關鍵字,將您的函數的返回值隱式轉換爲無極

爲了進一步說明這一點,觀察doSomething - 它是「異步」或者是「同步」?

// "synchronous" function 
 
const mult = (x,y) => x * y 
 

 
// "synchronous" function 
 
const double = (x) => mult (x, 2) 
 
    
 
// function with "callback" 
 
const doSomething = (x, callback) => 
 
    callback (x) 
 

 
// is it async ? 
 
doSomething (5, x => { 
 
    const result = double (x) 
 
    console.log (result) // 10 
 
}) 
 

 
// or is it sync ? 
 
console.log (doSomething (5, double)) // 10


哪裏何去何從

實際上在JavaScript異步更加統一的認識,現在 - 特別是與標準化和廣泛採用承諾。 ES2017也增加了新的控制語法async/await。 「回調」模式大部分已經死亡 - 即使是節點使用流行的「節點式(錯誤優先)回調」的主導力量也承認支持基於Promised的異步程序接口

這並不是說高階功能(與函數的參數,或者函數返回其他函數的函數),不會在它們的用途 - 你會看到功能程序員揮動Array.prototype.mapArray.prototype.reduce所有的地方

但是這種想法的「回調」可以非常強大 - 尤其是在以上述以外的方式表現時。 Continuation-passing style是我們通過延續(函數的另一個奇特名稱)作爲我們程序的「下一步」步驟。我在subject of continuations上寫了很多。如果你覺得這個東西有趣,請繼續閱讀。您將學習關於調用堆棧,遞歸原理,函子,單子,各種各樣的事情的驚人之處!

const cont = x => k => k (x) 
 

 
const double = x => cont (x * 2) 
 

 
const triple = x => cont (x * 3) 
 

 
double (2) (console.log)       // 4 
 
double (2) (double) (console.log)     // 8 
 
double (2) (double) (double) (console.log)   // 16 
 
double (2) (double) (double) (double) (console.log) // 32 
 
double (2) (triple) (console.log)     // 12

+1

這是一個很棒的解釋。它真的解決了我的誤解 –