【问题标题】:Javascript callback for two functions两个函数的Javascript回调
【发布时间】:2018-01-18 18:13:57
【问题描述】:

有没有办法用 Javascript (ES6) 实现下面的代码?

如果是,我该怎么做?我尝试了这个示例,但没有成功。

const funcA = (callback, arg1) => {
  console.log("Print arg1: " + arg1); /* Print arg1: argument1 */
  let x = 0;
  x = callback(x, );
  return x;
}

const funcB = (x, prefix) => {
  console.log("Print prefix: " + prefix); /* Print prefix: PREFIX_ */
  x = x + 1;
  return x;
}

/* Exec function funcA */
let x = funcA(funcB( ,"PREFIX_"), "argument1");
console.log("Value of x: " + x); /* Value of x: 1 */

【问题讨论】:

  • 您有空参数和前导逗号。你期待什么结果?
  • 我知道。但是我对空格和逗号的意思是参数是在不同的时间传递的。
  • 部分申请——这就是我想知道的!我的例子表明了这一点。 (请参阅接受的答案)。
  • @PedroGabrielLima 将x定义为默认参数funcA(x = () => funcB(x = 0 ,"PREFIX_"), "argument1");
  • @guest271314 我在你的例子中从控制台收到了这个错误:ReferenceError: can't access lexical declaration `x' before initialization.

标签: javascript ecmascript-6 callback


【解决方案1】:

这是一种使用定义的占位符作为符号来标识尚未设置的参数的方法。

它具有一个this 对象,该对象绑定到调用函数以进行进一步检查和评估。

如果arguments objectthis.arg的组合数组中没有placeholder项,则调用函数并返回函数调用。

如果没有,则新的参数数组绑定到函数并返回。

[?] 表示占位符

 funcB    x    prefix       this.args        args       action
-------  ---  ---------  -------------  --------------  ------------------------------
1. call  [?]  "PREFIX_"                 [?], "PREFIX_"  return calling fn w/ bound args
2. call   0      [?]     [?], "PREFIX_"  0,  "PREFIX_"  return fn call with args
3. call   0   "PREFIX_"                                 return 1

(当然它可以更短一些并委托给另一个函数,但这是一个概念证明。)

function funcA(callback, arg1) {
    console.log('funcA', callback, arg1)
    return callback(0, placeholder);
}

function funcB(x, prefix) {
    var args = this && this.args || [],
        temp = Array.from(arguments);

    console.log('funcB', isPlaceholder(x) ? '[?]' : x, isPlaceholder(prefix) ? '[?]' : prefix);

    // placeholder part
    if (temp.some(isPlaceholder)) {
        temp.forEach((a, i) => isPlaceholder(a) && i in args || (args[i] = a));
        return args.some(isPlaceholder)
            ? funcB.bind({ args })
            : funcB(...args);
    }

    // origin function body
    return x + 1;
}

const
    placeholder = Symbol('placeholder'),
    isPlaceholder = v => v === placeholder;

console.log("Value of x: " + funcA(funcB(placeholder, "PREFIX_"), "argument1"));

【讨论】:

  • 不错! +1。你能解释一下你的例子的一些细节吗? 1.在funcB中,变量“arguments”从哪里来?它是函数的默认参数吗? 2. 在输出中,打印了“funcB 0 [?]”和“funcB 0 PREFIX_”,这意味着funcB被调用了两次。所以第一次调用在funcA中绑定funcB,第二次调用返回的funcB(...args)? 3.第一次调用funcB是在"funcA(funcB(placeholder, "PREFIX_"), "arguments")",第二次调用是在"return callback(0, placeholder)"?
  • Javascript 中的每个函数都提供arguments object,这是一个类似数组的对象,包含实际函数的所有参数。没错,调用系列,正如你所说,但该函数被调用了三次。它总是检查arguments 列表中是否没有占位符。如果是,则返回原始函数体评估。
【解决方案2】:

在js中还不能部分应用。您需要另一个用作回调的箭头函数:

funcA(x => funcB(x ,"PREFIX_"), "argument1");

调用你不需要额外的逗号:

x = callback(x)

有些时候this proposal 可能允许这样写:

 funcA( funcB(?, "PREFIX_"), "argument1")

【讨论】:

  • 很好地参考了提案+1
  • @pedro 很高兴为您提供帮助 :)
【解决方案3】:

一种方法是定义一个默认参数,该参数是传递给funcA 的第一个参数的函数,并在调用funcA 时使用var 定义x

const funcA = (callback, arg1) => {
  console.log("Print arg1: " + arg1);
  let x = 0;
  x = callback(x, arg1);
  return x;
}

const funcB = (x, prefix) => {
  console.log("Print prefix: " + prefix);
  x = x + 1;
  return x;
}

/* Exec function funcA */
var x = funcA(x = () => funcB(x = 0 ,"PREFIX_"), "argument1");
console.log("Value of x: " + x);

【讨论】:

  • 如果您在我的示例中看到,我没有将 arg1 作为参数传递给回调。会有所不同吗?
  • @PedroGabrielLima 为什么你没有通过arg1 参数?这如何改变预期结果?你想达到什么目的?
  • 这个例子不是很清楚,但我在 funcB 中隔离参数的事实使代码模块化。在您的示例中,arg1 是 funcA 的一部分,但我希望 funcA 是不可变的。这样,如果想要将 funcC 而不是 funcB 传递给 funcA,它将不依赖于变量 arg1。我希望清楚这一点,呵呵。
  • 你的意思是arg1没有明确传递的地方prefix仍然会定义在funcB?也就是会设置一个默认值,默认值可以是相邻定义的参数?
  • @PedroGabrielLima 您可以将prefix 设置为funcN 的默认参数;例如,const fn = ({x = 0, prefix = "PREFIX_"} = {x:0, prefix:"PREFIX_"}) => { console.log(x, prefix) }; fn(); fn({x:2}); 另请参阅 Can we set persistent default parameters which remain set until explicitly changed?
猜你喜欢
  • 1970-01-01
  • 2021-08-01
  • 1970-01-01
  • 2013-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-03
  • 1970-01-01
相关资源
最近更新 更多