Angular 异步编程之(RxJs)初探

本节知识点是对【异步编程】的学习,首先我们来认识几个概念:

  • 什么是异步和同步?

  1. 同步的概念:执行一个方法或者功能,在没得到结果前,其他方法不执行,一定得等当前方法执行完,才会执行下一步骤;
  2. 异步的概念:执行一个方法或者功能,不需要等待到当前方法执行完,其他方法也可以执行;

同步比较符合我们常规思维,相对简单,容易理解接受,异步不会按规定格式(硬编码顺序)按步骤执行,执行无序,相对复杂,当然也就不易理解接受;

  • 异步编程的常用方案有哪些?

  1. Callback 回调函数的方式获取异步方法的数据,比如:JQuery 的 AJAX(基于XMLHttpRequest对象封装)就实现的异步编程;
  2. Promise(ES6)对象获取异步方法的数据;
  3. RxJs(第三方库/Microsoft获取异步方法的数据(ng 重度使用,比如:【HttpClient】对象);
  • 为什么选择【RxJs】?

为什么在 ng 中会使用 RxJs,并且基于此封装实现了【HttpClient】对象,接下来我们对上面提出的常用的异步编程的几种方案举例对比,由于我们整个过程中都是借助ES中的内置函数实现分别是 setInterval() & setTimeout();

  1. setInterval() 会周期性的重复执行;
  2. setTimeout() 定时延迟执行,只执行一次;
  • CLI 创建服务【request】;
ng generate service services/request
  • 创建组件【async】;
ng generate component components/async

 在组件中引入服务并注册声明;

//引入服务RequestService 
import { RequestService } from '../../services/request.service';

//引入rxjs工具函数,map & filter
import { map,filter } from 'rxjs/operators'; 

//在组件的构造函数DI注册服务request
constructor(public request:RequestService) { }

以上我们就把基础环境准备好了,接下来我们就实现以下几种方案:

  • Callback 回调函数方式实现异步编程;
//【request】服务中编写
//1.Callback回调函数
getCallbackData(cb:Function):void{
  //延迟1s执行
  setTimeout(() => {
    let userName:string = '1 => 1s后执行,CallbackData => 张三';
    cb(userName);
  }, 1000); //单位ms =》 1s = 1000ms

  console.log('2 => Callback回调函数'); //此行代码被执行
}

/*
//上面的【cb:Function】类似如下原生js的function
function cb(str:string):void {
      
}
*/

//在组件【async】的声明周期函数【ngOnInit】中使用上面服务中编写的方法
//生命周期函数,首次载入/加载或数据初始化(请求数据)使用
ngOnInit() {
  //1.callback获取异步方法的数据
  this.request.getCallbackData((data: any) => {
    console.log(data);
  });
}
  • Promise(ES6)对象获取异步方法的数据;
//【request】服务中编写
//2.Promise/ES6
getPromiseData(): Promise<any>{
   return new Promise<any>((resolve:any)=>{
      setTimeout(() =>{
        let userName:string = '2s后执行,PromiseData => 张三';
        resolve(userName);
      }, 2000);

      console.log('2 => Promise'); //此行代码不会被执行
   });
}

//在组件【async】的声明周期函数【ngOnInit】中使用上面服务中编写的方法
//生命周期函数,首次载入/加载或数据初始化(请求数据)使用
ngOnInit() {
  //2.Promise获取异步方法的数据
  let promiseData = this.request.getPromiseData();
    promiseData.then((data:any)=>{
      console.log(data);
  });
}
  • RxJs(第三方库/Microsoft)获取异步方法的数据;
//【request】服务中编写
//3.RxJs/Microsoft
getRxJsData(): Observable<any>{
  return new Observable<any>((observer:any)=>{
     setTimeout(() =>{
        let userName:string = '3s后执行,RxJsData => 张三';
        observer.next(userName);
        //observer.error('RxJsData => Error');
     }, 3000);
  });
}

//在组件【async】的声明周期函数【ngOnInit】中使用上面服务中编写的方法
//生命周期函数,首次载入/加载或数据初始化(请求数据)使用
ngOnInit() {
    //3.rxjs获取异步方法的数据
    let rxjsData = this.request.getRxJsData();
    //3.1【订阅|subscribe】
    rxjsData.subscribe((data:any)=>{
      console.log(data);
    }); 

    //3.2继续上面的方式演示【取消订阅|unsubscribe】
    let testUnsubscribe:Subscription = rxjsData.subscribe((data:any)=>{
      console.log(data);
    }); 
    //过1s后撤回上面的方法, testUnsubscribe 接收subscribe返回的信息
    setTimeout(() =>{
      testUnsubscribe.unsubscribe(); //unsubscribe 取消订阅
    }, 1000);
}
  • 对比 Pomise 对象和 RxJs 对象是否能执行多次方法调用;
//【request】服务中编写
//4.Promise多次执行(没有这个能力,只会执行一次)
getPromiseIntarvalData(): Promise<any>{
    return new Promise<any>((resolve:any)=>{
      setInterval(() =>{
        let userName:string = '定时轮询,每1s执行一次,PromiseData => 张三';
        resolve(userName);
      }, 1000);
    });
}

//5.rxjs多次执行
getRxJsIntervalData(): Observable<any>{
    return new Observable<any>((observer:any)=>{
      setInterval(() =>{
        let userName:string = '定时轮询,每1s执行一次,RxJsData => 张三';
        observer.next(userName); //通过内置next接收数据
        //observer.error('RxJsData => Error');
      }, 1000);
    });
}

//在组件【async】的声明周期函数【ngOnInit】中使用上面服务中编写的方法
//生命周期函数,首次载入/加载或数据初始化(请求数据)使用
ngOnInit() {
    //注意4和5演示的时候注意先注释,方便看演示结果
    //4.Promise执行多次(没有这个能力)
    let promiseIntervalData = this.request.getPromiseIntarvalData();
    promiseIntervalData.then((data:any)=>{
      console.log(data);
    });

    //5.rxjs执行多次,类似爬虫
    let rxjsIntervalData = this.request.getRxJsIntervalData();
    rxjsIntervalData.subscribe((data:any)=>{
      console.log(data);
    });
}
  • RxJs 对象工具函数【map & filter】对返回的数据进行处理;
//【request】服务中编写
//6.rxjs 工具函数【map & filter】对返回的数据进行处理
let rxjsIntervalNum = this.request.getRxJsIntervalNum();
    rxjsIntervalNum.subscribe((data:any)=>{
      console.log(data);
});

//在组件【async】的声明周期函数【ngOnInit】中使用上面服务中编写的方法
//生命周期函数,首次载入/加载或数据初始化(请求数据)使用
ngOnInit() {
    //6.rxjs 工具函数map & filter 对返回的数据进行处理
    let rxjsIntervalNum = this.request.getRxJsIntervalNum();
    rxjsIntervalNum.subscribe((data:any)=>{
      console.log(data);
    });

    /*
    //filter单个使用
    rxjsIntervalNum.pipe(  //pipe 管道
      //过滤count为偶数的数据
      filter((value) => {
        if (value % 2 ==0) {
          return true;
        }
      })
    ).subscribe((data:any)=>{
      console.log(data);
    });
    */
    
    /*
    //map单个使用
    rxjsIntervalNum.pipe(  //pipe 管道
      //对结果数据处理后再返回
      map((value) => {
        if (value % 2 ==0) {
          return value * value;
        }
      })
    ).subscribe((data:any)=>{
      console.log(data);
    });
    */

    //map & filter 联合使用
    rxjsIntervalNum.pipe(  //pipe 管道,可以有序的打包多个方法一并执行
      //1.先按条件过滤
      filter((value) => {
        if (value % 2 ==0) {
          return true;
        }
      }),
      //2.对过滤后的数据进行处理后再返回
      map((value) => {
        if (value % 2 ==0) {
          return value * value;
        }
      })
    ).subscribe((data:any)=>{
      console.log(data);
    });
}
  • Promise(ES6)和 RxJs 对比:
  1. Promise 通过【then】获取异步方法数据,RxJs的【Observable】对象通过【subscribe】获取异步方法数据;
  2. Promise执行方法后无法撤销,RxJs的【Observable】对象可以实现订阅【subscribe】和取消订阅【unsubscribe】;
  3. Promise只能执行一次(没有这个能力),RxJs的【Observable】对象可以执行多次(类似定向任务/轮询获取数据/爬虫);
  4. RxJs 的【Observable】对象可以延迟执行;
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ChaITSimpleLove

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值