虽然我理解Angular发出HTTP请求的方式,但我更喜欢使用内置的Fetch API,因为我不必为了发出一个简单的请求而订阅和取消订阅.我试着在我的angular应用程序中使用它,它没有抛出任何错误,页面没有重新加载(仍然是SPA),一切正常.我想每件事都有时间和地点.

这是:

fetch('/api/get_post_by_id/1').then(r => r.json()).then(j => { console.log(j); });

比这更简单:

const obs = this.http.get('/api');
obs.subscribe(() => { ... });
obs.unsubscribe();

基本上我的问题是,在开发Angular应用程序时使用Fetch API是错误的吗?

推荐答案

与开发过程中遇到的任何工具一样,每种工具都有优点和缺点,思考一下为什么要使用某个工具是很好的.

当我们看HttpClient时,它最初简化了XMLHttpRequest的混乱.正如$.ajax最初所做的那样,HttpClient是"Angular 解".它遵循了所有事物都是可观察事物的思想,既有优点(你可以将其与其他可观察事物混合搭配),也有缺点(它会增加很多inflating ).

Advantages of HttpClient

  • 它允许简单地混合和匹配两个可观察对象(例如,假设您有一个可观察对象返回多次,一个API请求返回一次,您希望将两者压缩在一起,这非常容易做到).当然,把一个promise 变成一个可观察的promise 只需要从rxjs中输入from
  • 如果你忘记了添加一个抽象——所有的请求都要经过apiService层——你仍然可以使用拦截器神奇地获得类似的结果.
  • 这将增加新开发人员的学习曲线,从而使你的工作更加特殊.
  • HttpClient为您带来了一些魔力,比如自动重试请求.
  • It's already included in Angular, so if you need to support 7 year old browsers like IE11 you don't need to load a polyfill like 具有 fetch.

Advantages of fetch

Important:所有与fetch相关的代码都假设您创建了一个非常简单的抽象(例如,在这些示例中为apiService).这与在HttpClient陆地上设置拦截器是一样的.

  • 这是新的行业标准.一旦你知道了它,它就可以在任何地方使用(最有可能的是一旦Angular 和react 消失——在某个时候,它们会——fetch仍然很可能在附近).

  • 它简化了服务人员的工作,因为RequestResponse对象与您在正常代码中使用的对象相同.

  • HTTP请求通常只返回一次(当然,您可能会逐块加载文件,但这是一个非常罕见的例外).fetch是围绕规范(单返回值)而不是异常(多个返回值)构建的,因此返回Promise而不是流式类型.这样做的好处是,它可以很好地与所有相关的新语言功能(如asyncawait)配合使用.比较:

     try {
         const posts = await this.apiService.get('/posts');
         // work 具有 posts
     } catch (error) {
         // handle error
     }
     console.log('this happens **after** the request completes');
    

    具有

     this.http.get('/posts')
         .subscribe(posts => {
             // work 具有 posts
         })
         .catch(error => {
             // work 具有 error
         });
     console.log('this happens **before** the request completes');
    

    (当然,你也可以 for each 可观察的对象添加toPromise个完整的代码(或者添加.pipe(take(1))个,但坦率地说,这是一堆多余的代码(我仍然经常使用这些代码))

  • 它简化了新人的入职.当你看到一个请求,比如

     this.apiService.get('/posts');
    

    来自任何框架的开发人员都可以过来,右键单击.get,查看函数定义,其中将明确定义要添加的域和身份验证头等内容.

    另一方面,当开发者看到

     this.http.get('/posts')
    

    除非他们意识到特定Angular 的魔力,否则他们无法轻松发现请求是否会被更改,以及更改的位置.这就是为什么认为Angular学习曲线陡峭的原因之一.

  • 不存在你没有意识到的魔法的风险,比如自动重试请求,这些请求可能会在服务器上触发同一个请求4次,而你不知道这是怎么可能的.

  • 它已经包含在浏览器中——前提是你不需要支持7年前的浏览器——因此它可以产生更小的Bundle 包大小.

Complete tie

  • 我真的不明白类型有什么区别,因为从任何方法输入返回值都是可以做到的.<Model>this.apiService.get('/posts')个很好用.

Conclusion

Personally, I would strongly recommend anybody to use fetch 具有 an abstraction layer. It results in easier to read code (even a junior who hasn't ever seen async and await is able to read it) and even if you are in a rare situation where your apiService has to return multiple times you are still completely free to do so as you're fully in control. And in general, you should only not use the standard (fetch) if the alternative offers significant advantages. Even if it was a perfect tie in terms of advantages and disadvantages it probably isn't worth going for a 'framework specific' solution.

HttpClient似乎除了在初始项目设置期间节省几分钟的时间之外,没有任何明显的优势,在初始项目设置期间,您不需要为API请求设置抽象层.

Typescript相关问答推荐

为什么空对象可以将类型断言为任何内容?

Angular 垫页分类和垫排序不起作用

如何在Jest中嘲笑location.back()方法调用进行Angular 组件测试?

在角形加载组件之前无法获取最新令牌

如何通过TypeScript中的工厂函数将区分的联合映射到具体的类型(如类)?

有没有办法解决相互影响的路由之间的合并?

如何在TypeScrip中使用嵌套对象中的类型映射?

ANGLE找不到辅助‘路由出口’的路由路径

从对象类型描述生成类型

TypeScrip泛型类未提供预期的类型错误

防止重复使用 Select 器重新渲染

正确使用相交类型的打字集

从route.参数获取值.订阅提供";无法读取未定义";的属性

自动通用回调

如何在Nextjs路由处理程序中指定响应正文的类型

字符串文字联合的分布式条件类型

如何使函数参数数组不相交?

React-跨组件共享功能的最佳实践

什么';是并类型A|B的点,其中B是A的子类?

如何使用动态生成的键和值定义对象的形状?