Typescript空回调函数

huangapple go评论72阅读模式
英文:

Typescript empty callback function

问题

在我的Angular项目中,我有一个方法,它接受两个回调函数,一个用于成功,一个用于失败,目前的代码如下:

somefunction(function(token) {
    console.log('Got token: ' + token);
  }, function(error) {
    console.log('Failed to get token', error);
});

假设我想保留错误处理,但不关心成功回调,那么什么是正确的方式来处理错误回调呢?
我应该创建一个空的成功方法吗,像这样:

somefunction(function(token) {
  }, function(error) {
    console.log('Failed to get token', error);
});

我应该将第一个参数设置为 null 吗?

somefunction(null, function(error) {
    console.log('Failed to get token', error);
});

我不确定使用 null 是否存在任何风险,或者是否应该只添加一个空函数(看起来多余)。

编辑:这个函数来自一个库,我希望不要修改这个库。

英文:

In my angular project i have a method that takes two callback functions, one for success one for fail which currently looks like:

somefunction(function(token) {
    console.log('Got token: ' + token);
  }, function(error) {
    console.log('Failed to get token', error);
});

Lets say I want to keep the error handling but im not interested in the success callback, what is the proper way to still handle the error callback?
Should I create an empty success method like:

somefunction(function(token) {
  }, function(error) {
    console.log('Failed to get token', error);
});

should i give null as first parameter?

somefunction(null, function(error) {
    console.log('Failed to get token', error);
});

Im not sure if there are any dangers of using null and I should just add an empty function (which looks redundant).\

edit: the function is from a library, I prefer to not touch the library.

答案1

得分: 2

I will try to give a more in-depth explanation of my comment. What you are doing seams to be an old school JavaScript coding the type of coding TypeScript was invented to prevent. In JavaScript you have two type of "empty" values that are similar but not the same null and undefined. For a while now in TypeScript all values are non nulluble by default that means unlike in JavaScript you will get a compiler error if you try to put null or undefined in a function. So if your somefunction looks like this.

function someFunction(success: (token: string) => void, error: (error:string) => void) {

}

A call like somefunction(null, (e) =>{}) will not compile at all because everything is not nullable by default. And you must give it an empty callback like somefunction(()=>{}, () =>{}) you can see that you don't event need the token parameter because any paraatreless function can be cast to a parameter function.
If the creator of some function allowed "null" in type script he would have defined like so

function someFunction(success?: (token: string) => void, error?: (error:string) => void) {

}

Where the ? is a shorter way of writing () => void | undefined. Now you can call it with someFunction(undefined, ()=>{}); but a call someFunction(null, ()=>{}); will produce an error since null is not equal (===) undefined. This is the most common way to allow empty calls to functions in TypeScript. If you really want a null value you can define somefunction like so

function someFunction(success: ((token: string) => void) | null, error: ((error:string) => void) | null) {
    
}

This is really uncommon in typescript and way two if what most people use.
But since you asked about "best practices" from what I can see what you are doing is some async workflow and modern JavaScript and typescript tend to preferer Promises and in angular Observables(The two are not mutually exclusive and can work well together).

英文:

I will try to give a more in-depth explanation of my comment. What you are doing seams to be an old school JavaScript coding the type of coding TypeScript was invented to prevent. In JavaScript you have two type of "empty" values that are similar but not the same null and undefined. For a while now in TypeScript all values are non nulluble by default that means unlike in JavaScript you will get a compiler error if you try to put null or undefined in a function. So if your somefunction looks like this.

function someFunction(success: (token: string) => void, error: (error:string) => void) {

}

A call like somefunction(null, (e) =>{}) will not compile at all because everything is not nullable by default. And you must give it an empty callback like somefunction(()=>{}, () =>{}) you can see that you don't event need the token parameter because any paraatreless function can be cast to a parameter function.
If the creator of some function allowed "null" in type script he would have defined like so

function someFunction(success?: (token: string) => void, error?: (error:string) => void) {

}

Where the ? is a shorter way of writing () => void | undefined. Now you can call it with
someFunction(undefined, ()=>{});
but a call someFunction(null, ()=>{}); will produce an error since null is not equal (===) undefined. This is the most common way to allow empty calls to functions in TypeScript. If you really want a null value you can define somefunction like so

function someFunction(success: ((token: string) => void) | null, error: ((error:string) => void) | null) {
    
    }

This is really uncommon in typescript and way two if what most people use.
But since you asked about "best practices" from what I can see what you are doing is some async workflow and modern JavaScript and typescript tend to preferer Promises and in angular Observables(The two are not mutually exclusive and can work well together).

答案2

得分: 1

如果你更喜欢使用更符合ES6的方法,你可以将这个函数包装成一个Promise。这将允许你在这个函数上使用thencatch方法。

一个简单的方法是创建一个新的Promise,并将resolvereject作为参数传递给函数。

let myPromise = new Promise((resolve, reject) => {
    somefunction((item) => { resolve(item) }, (error) => { reject(error) });
   // 或者甚至可以这样写 somefunction(resolve, reject);
});

然后你可以像处理其他Promise一样使用这个Promise。在你的情况下;

myPromise.catch((error) => {
    console.error(error);
});

这看起来对于你想要做的事情似乎有些过于繁琐,但你可以将其包装成一个函数,并在需要使用库函数的任何地方使用它。

function toPromise(fnc) {
    return new Promise((resolve, reject)  => fnc(resolve, reject));
}

toPromise(somefunction).catch((error) => {
   // 处理错误
});

这里我只使用了箭头函数,但如果你愿意,你也可以使用普通的回调函数。

英文:

If you prefer to use a much more ES6 way, you could wrap this function into a promise.
This will allow you to use the function then and catch on this function.

A simple way to do this is to create a new Promise and pass the resolve and reject as parameter to the function.

let myPromise = new Promise((resolve, reject) => {
    somefunction((item) => { resolve(item) }, (error) => { reject(error) });
   // or even somefunction(resolve, reject);
});

You can then use this promise as any other promise. In your case ;

myPromise.catch((error) => {
    console.error(error);
});

This seams far fetch for what you are trying to do, but you could wrap this into a function and use it everywhere you have to use the library function.

function toPromise(fnc) {
    return new Promise((resolve, reject)  => fnc(resolve, reject));
}

toPromise(somefunction).catch((error) => {
   //handle the error
});

Here i have use only arrow function, but you could use normal callback function if you'd like.

huangapple
  • 本文由 发表于 2020年1月6日 22:50:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/59614152.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定