- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我打算创建一个在调用回调之前调用的“预处理”函数。换句话说,调用回调应该遵循以下模式:预处理函数 -> 回调。为了“插入”这样的预处理函数,我可以简单地创建一个闭包,在闭包内重写回调,以便调用预处理函数,然后在重写的回调结束时,调用原始回调。
var end = function(init) {
/*
In here, init is processed.
Init contains multiple callbacks.
One callback is chosen to be invoked.
*/
init.callback();
};
var closure = function(init) {
var old = init.callback;
init.callback = function() {
/*
Do the preprocessual stuff
*/
console.log("The preprocessual functionality has now taken place.");
return old.apply(this, Array.prototype.slice.call(arguments));
};
return end.apply(this, Array.prototype.slice.call(arguments));
};
closure({
/*among other properties*/
callback: function() {
console.log("The preprocessual callback must have been invoked when 'end' invokes me.");
}
});
但是,我有多个回调,而我只有一个预处理函数。每次调用这些回调之前都应调用相同的预处理函数。为了不必为每个单独的可能回调编写预处理回调,我在闭包中创建了一个循环,将变量 old
分配给下一个回调,然后使用 Function 构造函数重写回调。
一切仍然有效。但是,我无法再在回调函数中使用它最初可以访问的非全局变量。以下崩溃,声称未定义 variable
(根据 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function )。
(function() {
var end = function(init) {
/*
In here, init is processed.
Init contains multiple callbacks.
One callback is chosen to be invoked.
*/
init.callback();
};
var closure = function(init) {
var old = init.callback;
init.callback = new Function(
"\
/*\
Do the preprocessual stuff\
*/\
console.log(\"The preprocessual functionality has now taken place.\");\
return " + old + ".apply(this, Array.prototype.slice.call(arguments));\
"
);
return end.apply(this, Array.prototype.slice.call(arguments));
};
var variable = "value";
closure({
/*among other properties*/
callback: function() {
console.log("The preprocessual callback must have been invoked when 'end' invokes me.");
console.log(variable);
}
});
})();
然后我想,让我们尝试将回调中所需的变量绑定(bind)到回调函数。然后我遇到了一个非常奇怪的问题。由于某种原因,将范围/参数绑定(bind)到回调函数(与 Function 构造函数几乎没有关系)会导致奇怪的错误。此类错误的一个小例子:
这有效
var callback = function() {
console.log(arguments);
};
callback = new Function(
"\
return " + callback + ".apply(this, Array.prototype.slice.call(arguments));\
"
);
callback(1, 2, 3);
这不起作用
var callback = function() {
console.log(arguments);
}.bind(this);
callback = new Function(
"\
return " + callback + ".apply(this, Array.prototype.slice.call(arguments));\
"
);
callback(1, 2, 3);
如果我将回调分配给另一个变量(例如 old
)并在 Function 构造函数中使用 old
也没关系,如果我在 Function 构造函数中使用了完全不同的绑定(bind)函数。任何绑定(bind)函数(无论是否使用变量引用)都会给我错误:“SyntaxError:元素列表后缺少 ]”。
事实上,即使这样也失败了
callback = new Function(
"\
return " + (function() {}.bind(this)) + ".apply(this, Array.prototype.slice.call(arguments));\
"
);
callback(1, 2, 3);
我不明白为什么会出现这种情况。有用的帮助将不胜感激。
根据要求,实际用例:
var
ajax = function(init) {
for (var i = 0, callbacks = ["success", "error"]; i < callbacks.length; i++) {
if (init.hasOwnProperty(callbacks[i] + "Callback")) {
init[callbacks[i] + "Callback"] = new Function("responseText",
"\
/*\
Preprocessual callback takes place here (among other things, messages from the server are inserted in the document)\
*/\
\
return " + init[callbacks[i] + "Callback"] + ".apply(this, Array.prototype.slice.call(arguments));\
"
);
}
}
// This is the actual ajax function, which can operate independently of the project (in contrary, the preprocessual callback needs to know about where to insert messages in the document)
return cregora.ajax.apply(this, Array.prototype.slice.call(arguments));
}
;
(function() {
// some scope with variables..
ajax({
url: "url",
callbackThis: this,
successCallback: function(responseText) {
console.log("I need some variables available in this scope");
},
errorCallback: function() {
console.log("I need some variables available in this scope");
}
});
})();
最佳答案
正如我所料,您实际上使问题有点过于复杂了。
您可以构建一个高阶函数,该函数返回适当的处理程序并自动包装该函数(如预处理器),而不是使用函数构造函数。
var callbackWrapper = function (callback) {
// Returns new anonymous function that acts as the handler
return function responseHandler (responseText) {
// Do your pre-processing
console.log(responseText);
callback.apply(this, Array.prototype.slice.call(arguments));
};
};
var ajax = function(init) {
for (var i = 0, callbacks = ["success", "error"]; i < callbacks.length; i++) {
var callbackName = callbacks[i] + "Callback";
if (init.hasOwnProperty(callbackName)) {
var callback = init[callbackName];
init[callbackName] = callbackWrapper(callback);
}
}
// This is the actual ajax function, which can operate in independent of the project (for example, the preprocessual callback needs to know about where to insert messages in the document)
return cregora.ajax.apply(this, Array.prototype.slice.call(arguments));
};
(function() {
// some scope with variables..
ajax({
url: "url",
callbackThis: this,
successCallback: function(responseText) {
console.log("I need some variables available in this scope");
},
errorCallback: function() {
console.log("I need some variables available in this scope");
}
});
})();
如果您愿意,您甚至可以更改callbackWrapper,使其每次都使用完全相同的预处理器函数:
var callbackWrapper = (function createCallbackWrapper () {
var preProcessor = function (responseText) {
console.log(responseText);
};
return function callbackWrapper (callback) {
// Returns new anonymous function that acts as the handler
return function responseHandler (responseText) {
var args = Array.prototype.slice.call(arguments);
preProcessor.apply(this, args);
callback.apply(this, args);
};
};
})();
现在绑定(bind)原始回调函数将不再有任何问题。
关于这个问题的更多解释:
当你使用fn + ".apply(...)"
时,JS会将原函数转为字符串。这就是为什么您将很难访问闭包变量或任何不在您的 varclosure
函数范围或全局范围内的其他内容。
在您的情况下它也会失败,因为在函数上调用 .bind
后,其字符串表示形式变成 "function () { [native code] }"
。这当然不是一个有效的函数体,并且会给你带来很多麻烦。
转换为字符串是实际问题,而且是一个不容易解决的问题。因此,使用 new Function 几乎从来都不是正确的解决方案,一旦您发现自己使用它,您应该假设您在推理中犯了错误。如果您没有这样做,并且 new Function
确实是唯一的解决方案,您就会知道。
关于javascript - 绑定(bind)要在 Function 构造函数内使用的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23200611/
我有一个 foo 类,它有一个 bar 方法,它接受可调用的东西(函数指针/仿函数)。这个可调用的东西应该作为绑定(bind)元素传递给另一个方法 doit 和第三个方法 bar_cb 方法。 #in
我正在尝试在我的 WPF 4.0 应用程序(使用 VS 2010 Pro RTM)中创建自定义 TabItem 模板/样式,但尽管一切似乎都正常工作,但我注意到跟踪窗口中存在绑定(bind)错误。 我
作为一名刚接触 Android 的开发人员,我想我可能误解了绑定(bind)服务。 我创建了一项服务来结束对服务器的访问。作为此服务的一部分,该服务正在监听多播地址,以识别本地网络上的设备何时出现和消
这个问题在这里已经有了答案: What is the use of the JavaScript 'bind' method? (23 个回答) 关闭 7 年前。 所以我一直在尝试了解一些 JS 上
我不明白这三种语法之间的区别: where a = f (b) do a <- f (b) do let a = f (b) 我确实明白了a <- f(b)与其他两个不同,在大多数情况下,我尝试了所有
我在将 Cocoa 项目从手动同步接口(interface)模型转换为绑定(bind)模型时遇到问题,这样我就不必担心接口(interface)粘合代码。 我关注了 CocoaDevCentral C
我正在尝试找出一种好的方法来对处理大数据集的代码进行并行化,然后将结果数据导入 RavenDb。 数据处理受 CPU 限制和数据库导入 IO 限制。 我正在寻找一种解决方案,以对 Environmen
我正在 foreach 循环中生成单选按钮。我试图将选中的属性绑定(bind)到父级中的基本可观察值。不幸的是,当单击单选按钮时,父级的属性似乎没有在单击处理程序中更新。 基于一些previous w
在我的 Windows Phone 应用程序中,我有两个 LongListSelectors并排在页面上。我想做到这一点,以便当用户滚动其中一个时,另一个滚动相同的量。 两个 LongListSele
我在网上看到这个问题准备面试: Given a non-preemptive kernel which type of process will get affected morein terms o
我有一个 foreach 绑定(bind),如下所示: Summary Permitting 原因是有两个选项卡始终存在,并且我根据是否添加了其他选项卡来添加其他选项
任何人都有绑定(bind)相同的情况DataContext到 TextBlock 中的 Text 属性(例如)。 我必须分配 DataContext以我的风格反射(reflect)基于 Datacon
给定以下代码: Login 和下面的javascript $(function () { $('#btnLogin').click(function () { co
我使用 boost::asio 创建了一个服务器。我在绑定(bind)到端点时遇到问题。所以,如果我在构造函数中初始化一个接受器: Server::Server(QWidget *parent) :
我正在将现有项目从 MySQL 转换为 Postgres。代码中有相当多的原始 SQL 文字使用 ? 作为占位符,例如 SELECT id FROM users WHERE
似乎在绑定(bind)某些数据时出错了,有人可以帮我解决我哪里出错了,尽管我无法弄清楚。 真的不需要在这里显示太多,这是 Binding,我已经通过移除背景并在其中放置颜色来测试背景,效果很好。 编辑
我正在尝试使用 wcf 构建一个 http 监听器(web 服务)。这个监听器是一个更大的桌面应用程序的一部分。此桌面应用程序还会调用 http 监听器。 当监听器接收到数据时,它应该被传递到桌面应用
嘿嘿。 我正在使用 Node.JS 和 child_process 来生成 bash 进程。我试图了解我是否正在执行 I/O 绑定(bind)、CPU 绑定(bind)或两者兼而有之。 我正在使用 p
尝试执行以下操作并出现“Got interpolation ({{}}) where expression was expected”错误。 {{item.name}} 谢谢!
我有一个导入的 Java 库,它是我解决方案中的“绑定(bind)库”项目。 我正在尝试从解决方案中的另一个项目绑定(bind)到第 3 方库中的服务。 第 3 方库文档 [在 java 中] 非常简
我是一名优秀的程序员,十分优秀!