在开发新产品时,我创建了一个后端和前端项目。对于前端,我使用带有Typescript的角度框架。下面是一个问题,因为我对这门语言还不熟悉(几天前)。我的问题是关于回调以及如何避免“this”上下文中的显式传递。我已经阅读了一些资源,我将链接它们。
下面我将为HttpClient实现一个包装器。快速版本是使用插件架构(由角度路由支持)的模块进行流控制,最好是通过使用观察员和订阅者广播401之类的错误以实现优雅的重新进入(在我看来)-我们不会讨论这个问题,但提到上下文可能会有所帮助。
下面是我的代码的基本部分:包装器=
export class WebService {
constructor(private httpClient: HttpClient,
private exceptionService: ExceptionService<Exception>) { }
public post<T>(url: string, dataToPost: any, callBack: (responseData: T) =>
void, callBackInstance: any): void {
this.httpClient.post<T>(url, dataToPost).subscribe(
(data: T) => {
callBack.call(callBackInstance, data);
},
(error: HttpErrorResponse) => {
this.exceptionService.notify(error);
}
);
现在,我可以使用显式管理回调的“this”上下文。调用()以插入它。我不介意在您的任何建议中使用它-但是查看签名,您会发现该方法要求您在所需的“this”上下文中传递(callbackInstance)。这就把一些责任推到了我不想要的方法调用方身上。对我来说,一个类非常像一个以“this”作为初始置换的数组——因为我正在为回调传递方法;是否真的没有办法检查该方法以得出适当的“this”?大致如下:callbackInstance=callback。getRelativeContext();回拨。调用(回调实例、数据);这将消除额外的参数,使我的团队使用的方法不那么容易出错。
欢迎链接到参考资料,但如果可能,请尽量缩小到相关部分。
链接:
用于更新“this”上下文
参数回调
编辑:从我导出并放置在测试用例中的已接受答案:
const simpleCallback = (response) => {holder.setValue(response); };
service.post<LoginToken>(Service.LOGIN_URL, '', simpleCallback);
如果需要将上下文传递给回调,那么回调本身将依赖于该上下文:
function explicitContext(callback, context) {
const arg = 1;
callback.call(context, arg);
}
function implicitContext(callback) {
const arg = 1;
const someCleverContext = {importantVal: 42, importantFunc: () => {}};
callback.call(someCleverContext, arg);
}
如果我们需要实际访问回调中的上下文,请考虑使用情况:
function explicitUsage() {
const someCleverContext = {importantVal: 42, importantFunc: () => {}};
const callback = function(arg) {this.importantFunc(arg);}
explicitContext(callback, someCleverContext);
}
function implicitUsage() {
const callback = function(arg) {this.importantFunc(arg);}
implicitContext(callback);
}
在这两种情况下,我们实际上都在泄露上下文的细节,并迫使消费者承担一些责任!现在,如果我们真的需要传递上下文,没有一种神奇的方法可以绕过它。好消息是,我们可能一开始就不需要传递上下文。
export class WebService {
constructor(
private httpClient: HttpClient,
private exceptionService: ExceptionService<Exception>)
{ }
public post<T>(url: string, dataToPost: any, callBack: (responseData: T) => void): void {
this.httpClient.post<T>(url, dataToPost).subscribe(
(data: T) => {
callBack(data);
},
(error: HttpErrorResponse) => {
this.exceptionService.notify(error);
},
);
}
}
通过这种方式,我们可以让客户机代码只关心responseData,如果他们需要一些巧妙的上下文,他们可以自行绑定它:
function usage() {
let webService: WebService;
const simpleCallback = (response) => {console.log(response);} // can inline too
webService.post('/api', {data: 1}, simpleCallback);
const cleverContextCallback = function(response) {this.cleverLog(response)};
const cleverContext = {cleverLog: (data) => console.log(data)};
const boundCallback = cleverContextCallback.bind(cleverContext);
webService.post('/api', {data: 1}, boundCallback );
}
说了这么多,我肯定会建议从您的服务中返回可观察到的。
export class WebService {
constructor(
private httpClient: HttpClient,
private exceptionService: ExceptionService<Exception>)
{ }
public post<T>(url: string, dataToPost: any, callBack: (responseData: T) => void): Observable<T> {
const observable = this.httpClient.post<T>(url, dataToPost);
// Note that httpClient.post automatically completes.
// If we were using some other library and we would want to close the observable ourselves,
// you could close the observable yourself here after one result:
if ('we need to close observable ourselves after a result') {
return observable.pipe(take(1));
}
if ('we need to handle errors') {
return observable.pipe(
catchError(error => {
this.exceptionService.notify(error);
if ('We can fallback') {
return of('Fallback Value');
} else {
throw new Error('OOPS');
}
}),
);
}
return observable;
}
}
处理服务内部的错误、关闭和其他杂务将让服务的消费者专注于来自响应的数据。
我正在尝试将一个项目迁移到Android Room。阅读了Android Room文档后,我注意到Singleton适合访问我的数据库。 Android开发者的报价: 注意:如果您的应用程序在单个进程中运行,则在实例化AppDatabase对象时应遵循单例设计模式。每个RoomDatabase实例都相当昂贵,您很少需要在单个进程中访问多个实例。 我编写了以下代码: 只是一个简单的双重检查锁定单例。
问题内容: 如何传递上下文?我想打电话,如果在1000毫秒。我怎样才能做到这一点? 当我尝试上述操作时,指的是窗口。 问题答案: 编辑: 总而言之,早在2010年,当有人问这个问题时,解决此问题的最常用方法是保存对进行函数调用的上下文的引用,因为执行函数时要指向全局对象: 在一年前发布的ES5规范中,它引入了该方法,但最初的答案中并未建议使用该方法,因为该方法尚未得到广泛支持,您需要使用polyf
问题内容: 上周受本文启发,我正在重构我必须更明确地将上下文(数据库池,会话存储等)传递给处理程序的应用程序。 但是,我遇到的一个问题是,如果没有全局模板映射,我的自定义处理程序类型(要满足)上的方法将无法再访问该映射以呈现模板。 我需要保留全局变量,或者将我的自定义处理程序类型重新定义为结构。 有没有更好的方法来实现这一目标? func.go struct.go 有没有更干净的方法将实例传递给?
本文向大家介绍JS中this上下文对象使用方式,包括了JS中this上下文对象使用方式的使用技巧和注意事项,需要的朋友参考一下 JavaScript 有一套完全不同于其它语言的对 this 的处理机制。 在五种不同的情况下 ,this 指向的各不相同。 有句话说得很在理 -- 谁调用它,this就指向谁 一、全局范围内 在全局范围内使用this ,它将指向全局对象(浏览器中为 window) 二、
问题内容: 每当关于Java同步的问题浮出水面时,有些人就会很想指出应该避免的事情。他们声称,取而代之的是,最好是锁定私有引用。 给出的一些原因是: 一些邪恶的代码可能会窃取你的锁(非常流行,也有一个“偶然”的变体) 同一类中的所有同步方法都使用完全相同的锁,这会降低吞吐量 你(不必要地)暴露了太多信息 包括我在内的其他人则认为,这是一个惯用语言(在Java库中也是如此),是安全且易于理解的。应当
问题内容: 最近,我开始修补React.js,我喜欢它。我开始使用常规的ES5,以便掌握所有内容,所有文档均使用ES5编写… 但是现在我想尝试一下ES6,因为它有光泽而且是新的,而且似乎确实简化了某些事情。让我感到困扰的是,对于我添加到组件类中的每个方法,现在都必须将“ this”绑定到该方法,否则它将无法正常工作。所以我的构造函数最终看起来像这样: 如果我要在类中添加更多方法,这将变得更大,更难