关于前端:angular-8中使用observable使用asyncawait

不废话,间接上论断,jsobservable不能间接应用async/await这种流程管制标识,举个例子

  observable:Observable<any> = new Observable;

  constructor() { 
    this.observable = Observable.create((item:any)=>{//一秒钟后输入后果
      setTimeout(()=>{
        item.next('后果');
        item.complete();
      },1000)
    })
  }

  ngOnInit() {
    console.log(1);
    let startTime = new Date().getTime()
    this.observable.subscribe((res)=>{
      let endTime = new Date().getTime()
      let result = Math.floor(new Date(endTime-startTime).getTime()/1000);
      console.log(res,' 耗时',result,'秒')
    })
    console.log(2)
  }

不言而喻,执行后果是

那么,我想像promise那样应用async/await是否能够呢?
ngOnInite()办法进行稍加改变,加上async/await

  async ngOnInit() {
    console.log(1);
    let startTime = new Date().getTime()
    await this.observable.subscribe((res)=>{
      let endTime = new Date().getTime()
      let result = Math.floor(new Date(endTime-startTime).getTime()/1000);
      console.log(res,' 耗时',result,'秒')
    })
    console.log(2)
  }

啊哈,不好,编辑器提醒了

不行邪,运行看看

正如下面说的,流程管制并没有起作用,Observable不反对间接的流程管制。

解决办法有两个,首先说一个简略状况下的解决办法
第一种、转为promise 操作如下

 async ngOnInit() {
    console.log(1);
    let startTime = new Date().getTime()
    await this.observable.toPromise().then((res)=>{
      let endTime = new Date().getTime()
      let result = Math.floor(new Date(endTime-startTime).getTime()/1000);
      console.log(res,' 耗时',result,'秒')
    })
    console.log(2)
  }

间接利用.toPromise()办法将其转为promise,这样async/await就起作用了,当然,也要应用promise中的then办法才行。

能够看到,当初程序会期待promise执行结束当前才会输入2,也就是流程管制失效了。

留神 有些敌人手动写observable的时候,没有在外面写complete,这样执行toPromise的时候,并不会运行then外面代码,因为promise在底层代码实现之前是不会进行解析的,也就是手写observable中肯定要记得写complete

当然,转换成promise并不能解决所有问题,比方上面这种状况

当用户点开页面的时候,须要同时收回50个申请,然而用户很可能在所有数据申请完结之前就会跳走,所以很可能20-30个申请都是有效申请,那么,有效申请就须要间接勾销掉

咱们晓得promise是不可能勾销曾经收回的申请的,你能够通过throw或者reject触发promisecatch操作,然而这只是代表你不在对发出请求的后果关怀,申请仍然存在,后果仍然会返回。
除非用户在所有申请实现之前点击了浏览器的进行加载按钮,

那申请就会从pending状态变成了cancel

或者,应用subscribe,这也是其比照promise的劣势之一
勾销subscribe申请很简略:
单个申请的状况下

   this.observable.subscribe((res)=>{}).unsubscribe()

间接在前面加上unsubscribe就行,这个申请会变成cancel状态,不会再占用申请资源

那么, 回到下面的问题,简化一下就是,我可不可以,即能勾销曾经收回的申请,又能控制代码的流程呢?答案是必定的,只有把promiseobservable一起搭配应用就行
第二种解决办法、 终极版代码如下

  observableArray:Subscription=new Subscription;
  observable:Observable<any> = new Observable;

  constructor() { 
    this.observable = Observable.create((item:Observer<any>)=>{
      setTimeout(()=>{
        item.next('实现');
        item.complete();
      },1000)
    })
  }

  async ngOnInit() {
    console.log(1);
    let startTime = new Date().getTime()
    await new Promise((resolve,reject)=>{
      this.observableArray.add(this.observable.subscribe((res)=>{
        resolve(true)
        let endTime = new Date().getTime()
        let result = Math.floor(new Date(endTime-startTime).getTime()/1000);
        console.log(res,' 耗时',result,'秒')
      }))
    })
    console.log(2)
  }

  ngOnDestroy(): void {
    this.observableArray.unsubscribe()
  }

运行后果为

思路就是通过promise控制代码流程,而后利用对象接管Observable,管制申请的勾销与否

这样,即能够依照本人的志愿随时勾销曾经收回的申请,同时,也能控制代码的流程

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理