2017-10-15 102 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

这是一个很棒的解释。它真的解决了我的误解 –