javascript - 为元数据分配和查询 Javascript 箭头函数
问题描述
问题比较简单。我们需要为函数注入一个参数,然后简单地从函数体中提取该参数。我将在打字稿中呈现大纲......
abstract class Puzzle {
abstract assign(param, fn): any;
abstract getAssignedValue(): any;
async test() {
const wrapped = this.assign(222, async () => {
return 555 + this.getAssignedValue();
});
console.log("Expecting", await wrapped(), "to be", 777);
}
}
让我们设置场景:
- 假设严格模式,没有参数或被调用者。在最新版本的 v8 上应该可以很好地工作。
- 传递给的函数
assign()
必须是不带任何参数的匿名箭头函数。 - ……它也是
async
。分配的值可以在调用期间存储在某个地方,但是由于该函数是async
并且可以具有await
s,因此您不能依赖于通过多个交错调用来保持值。 this.getAssignedValue()
不接受任何参数,返回我们使用该assign()
方法分配的任何内容。
找到我在下面介绍的更优雅的解决方案会很棒。
编辑
好的,我们似乎找到了一个受 zone.js 启发的好的可靠解决方案。那里解决了相同类型的问题,解决方法是重写一些系统级原语的含义,例如 SetTimeout 和 Promise。上面唯一令人头疼的是 async 语句,这意味着函数的主体可以有效地重新排序。异步最终是由 Promise 触发的,所以你必须用上下文感知的东西来覆盖你的 Promise。它涉及很多,而且因为我的用例不在浏览器甚至节点之外,所以我不会让你厌烦细节。对于大多数遇到此类问题的人来说——只需使用 zone.js。
解决方案
哈克解决方案 1
我们实际上有一个有效的实现。这是一个非常痛苦的 hack,但证明这应该是可能的。不知何故。也许甚至有一个超级简单的解决方案我只是因为我已经盯着这个太久而错过了。
class HackySolution extends Puzzle {
private readonly repo = {};
assign(param: any, fn) {
// code is a random field for repo. It must also be a valid JS fn name.
const code = 'd' + Math.floor(Math.random() * 1000001);
// Store the parameter with this code.
this.repo[code] = param;
// Create a function that has code as part of the name.
const name = `FN_TOKEN_${code}_END_TOKEN`;
const wrapper = new Function(`return function ${name}(){ return this(); }`)();
// Proceed with normal invocation, sending fn as the this argument.
return () => wrapper.call(fn);
}
getAssignedValue() {
// Comb through the stack trace for our FN_TOKEN / END_TOKEN pair, and extract the code.
const regex = /FN_TOKEN_(.*)_END_TOKEN/gm;
const code = regexGetFirstGroup(regex, new Error().stack);
return this.repo[code];
}
}
因此,我们解决方案中的想法是检查 的堆栈跟踪new Error().stack
,并将我们可以提取的东西包装为令牌,然后我们将其放入回购中。哈基?非常hacky。
笔记
测试表明这实际上是相当可行的,但需要比我们拥有的更现代的执行环境——即 ES2017+。
推荐阅读
- arrays - 类型“any[]”上不存在属性“contactId”
- javascript - 在已部署应用程序的浏览器上可以看到源的实际文件系统路径
- sql - Oracle SQL 如何使用正则表达式构建字符串?
- angular - 添加 AngularMultiSelectModule 后 app.module.ts 中的错误
- vb.net - Addhandler [process].Exited 使 windows 服务停止
- postgresql - PostgreSQL:如何让函数存储它的最后一个返回值?
- django - 如何在 django 中将文件上传到 azure-storage 时获取文件路径
- python - 我想知道为什么我的程序没有在我的 while 循环中停止
- php - .toLocaleString('fr-FR') 不显示空格,但在控制台中工作
- xamarin.ios - Xamarin 中 Mac 和 iOS 平台的输入控件中的文本未设置为垂直居中