当前位置: 首页 > 面试题库 >

将变量绑定到回调函数

鲜于允晨
2023-03-14
问题内容

我的控制器中有一些函数可以调用一些数据库函数。所有这些数据库函数都执行“错误回调”,这意味着如果发生数据库错误,它们将执行一个单独的回调来处理该错误。例:

exports.referralComplete = function(req, res){
    /*getting id etc.*/
    db.startDatabaseConnection(function() {
        db.flagReferralAsDone(id, function(success) {
            db.endDatabaseConnection();
            /*doing stuff on success*/
        }, onError);
    }, onError);

    function onError(err, description) {
        logger.error(description + ": " + err);
        user.pageNotFound(req, res);
    }
}

我有与此相似的多个函数,它们正在调用不同的数据库函数。问题是我目前已将onError()复制到每个函数的作用域中,因为在处理错误时我需要req和res变量。我当然可以将res和req传递给数据库函数,然后将它们作为参数传递给错误回调,但是我想可能会有更好的方法。

因此,问题是:是否可以以某种方式将res和req绑定到全局onError回调函数,而不必将变量作为参数传递给db函数?

一般来说,我对node.js和javascript还是很陌生,所以如果有更好的错误处理方法,请告诉我。


问题答案:

绑定很简单!

db.startDatabaseConnection(function(){
  // whatever
}, onError.bind(this, var1, var2));

即使该链接有点长,也可以通过单击此很棒的链接来了解有关绑定的更多信息。

这是一个真正的基本演示

// a function
var something = function (a, b, c) {
  console.log(a, b, c);
};

// a binding of something with 3 defined args
var b = something.bind(null, 1, 2, 3);

// call b
b();
//=> 1 2 3

在幕后,这基本上是正在发生的事情

// ES6
const myBind = (f, context, ...x) =>
  (...y) => f.call(context, ...x, ...y);

// ES5
var myBind = function(fn, context) {
  var x = Array.prototype.slice.call(arguments, 2);
  return function() {
    var y = Array.prototype.slice.call(arguments, 0); 
    return fn.apply(context, x.concat(y));
  };
};

var b = myBind(console.log, console, 1, 2, 3);

b();
// => 1 2 3

b(4,5,6)
// => 1 2 3 4 5 6

上下文?

上下文允许您动态更改this功能。注意,您只能绑定用function关键字定义的函数的上下文;箭头函数具有this无法操纵的词汇。为了完整起见,显示了此内容,但我建议不要使用此类程序。通常最好只使用另一个函数参数,而不要依赖动态函数上下文this。支持这样的上下文切换是为了在JavaScript中启用面向对象的样式。除非您使用这种样式,否则我认为没有理由注意上下文。

const getCanvas = (id) =>

  document.getElementById(id).getContext('2d')



const draw = function (canvas, x = 0, y = 0)

{ canvas.beginPath()

  canvas.strokeStyle = this.color             // `this` refers to context!

  canvas.rect(x, y, this.width, this.height)  // `this` refers to context!

  canvas.stroke()

}



// create two contexts

const contextA =

  { color: 'blue', width: 10, height: 10 }



const contextB =

  { color: 'green', width: 10, height: 20 }



// bind the draw function to each context and the canvas

const drawA =

  draw.bind(contextA, getCanvas('main'))



const drawB =

  draw.bind(contextB, getCanvas('main'))



// call the bound drawing functions normally

// draw three blue squares

drawA(0, 0)

drawA(20, 0)

drawA(40, 0)



// and one green rect

drawB(80, 0)


<canvas id="main"></canvas>

部分申请

类似于binding is Partial
Application

在计算机科学中,部分应用程序(或部分函数应用程序)指的是将多个参数固定到一个函数,从而产生另一个arity较小的函数的过程。

在这里,我们可以制作一个非常简单的partial帮助程序,以帮助我们完成此任务

const identity = x =>

  x



const partial = (f = identity, ...x) =>

  (...y) => f (...x, ...y)



const foo = (...all) =>

  console.log ('array of', all)



partial (foo, 1, 2, 3) (4, 5, 6)

// 'array of', [ 1, 2, 3, 4, 5, 6 ]

咖喱

固化与绑定或部分应用有关,但不相同

在数学和计算机科学中,柯里化是一种将接受多个自变量(或自变量元组)的函数的评估转换为评估每个具有一个自变量的函数序列的技术。

const identity = x =>

  x



const curry = (f = identity, arity = f.length) => x =>

{

  const next = (xs = []) =>

    xs.length >= arity

      ? f (...xs)

      : x => next ([ ...xs, x ])

  return next ([ x ])

}



const foo = (a, b, c) =>

  console.log ('a', a, 'b', b, 'c', c)



curry (foo) (1) (2) (3)

// 'a' 1 'b' 2 'c' 3



curry (foo) ('choo') ('bye') ()

// 'a' 'choo' 'b' 'bye' 'c' undefined


 类似资料:
  • 问题内容: 我试图弄清楚如何将AngularJS范围变量绑定到CSS语法中。我认为问题出在花括号中。这是我基本上想做的事情: 关于如何实现这一目标的任何想法?谢谢! 问题答案: 如此处所述, angular不会在样式标签内的内容上运行。在那篇文章中有一个解决方法,但是作为一种更灵活的方法,我只是创建一个指令来获取内容,解析它们并替换: 更新的答案 用法: http://jsfiddle.net/V

  • 我有一个返回列表的函数。我试图在drools when子句中调用此函数,并将其绑定到名为l1的变量。如果像这样绑定变量,则子句不会执行。然而,如果我以类似的方式绑定映射,则执行then子句中的语句。我正在使用最新版本的drools。 这是代码 这里规则'test1'执行并打印值。但是我没有看到规则'test2'的任何输出。 任何帮助都将不胜感激。

  • Rust 通过静态类型确保类型安全。变量绑定可以在声明变量时标注类型。不过在多数情况下,编译器能够 从字面内容推导出变量的类型,大大减少了标注类型的负担。 使用 let 绑定操作可以将值(像具体数据)绑定到变量中。 fn main() { let an_integer = 1u32; let a_boolean = true; let unit = (); // 将

  • 变量绑定默认是不可变的,但加上 mut 修饰语后变量就可以改变。 fn main() { let _immutable_binding = 1; let mut mutable_binding = 1; println!("Before mutation: {}", mutable_binding); // 正确代码 mutable_binding += 1

  • 问题 你想要把一个回调与一个对象绑定在一起。 解决方案 $ -> class Basket constructor: () -> @products = [] $('.product').click (event) => @add $(event.currentTarget).attr 'id' add: (product) ->

  • 问题内容: 我有一个简单的删除按钮,该按钮可以接受字符串或数字,但不接受ng-model变量(不确定这是否是正确的术语)。 会产生: 但是,单击时什么也没有发生。如果我对变量进行硬编码,那么它就可以正常工作。我以为我不是在以“角度”方式做事,但是我不确定那是什么方式:) 这是我的控制器代码: 问题答案: 您无需在中使用大括号(),请尝试以下操作: