Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 通过RxJS操作符限制可观测的网络请求_Angular_Typescript_Rxjs - Fatal编程技术网

Angular 通过RxJS操作符限制可观测的网络请求

Angular 通过RxJS操作符限制可观测的网络请求,angular,typescript,rxjs,Angular,Typescript,Rxjs,我有一些数据通过网络请求进入Angular应用程序的一个组件。这是一个可观察的,看起来像这样: this.streamFiltersService.getByFilters( this.page - 1, this.pagesize, this.currentStage, this.language = filters['language'], this.location = filters['location'], this.zipcode = filt

我有一些数据通过网络请求进入Angular应用程序的一个组件。这是一个可观察的,看起来像这样:

    this.streamFiltersService.getByFilters(
        this.page - 1, this.pagesize, this.currentStage, this.language = filters['language'], this.location = filters['location'],
        this.zipcode = filters['zip'], this.firstName = filters['firstName'], this.lastName = filters['lastName'],
        this.branch = filters['branch'], fn);
    let fn = resRecordsData => {
        this.records = resRecordsData;
    };
public onFilterReceived(values)
{
    let filters = {};

    if (values) {
        filters = values;
    }

    this.route.params.subscribe(
        (params: any) => {
            this.page = params['page'];
        }
    );

    console.log('onFilterReceived() firing...');

    let fn = resRecordsData => {
        this.records = resRecordsData;
    };

    this.streamFiltersService.getByFilters(
        this.page - 1, this.pagesize, this.currentStage, this.language = filters['language'], this.location = filters['location'],
        this.zipcode = filters['zip'], this.firstName = filters['firstName'], this.lastName = filters['lastName'],
        this.branch = filters['branch'], fn);
}
这里有一个名为
fn
的回调,如下所示:

    this.streamFiltersService.getByFilters(
        this.page - 1, this.pagesize, this.currentStage, this.language = filters['language'], this.location = filters['location'],
        this.zipcode = filters['zip'], this.firstName = filters['firstName'], this.lastName = filters['lastName'],
        this.branch = filters['branch'], fn);
    let fn = resRecordsData => {
        this.records = resRecordsData;
    };
public onFilterReceived(values)
{
    let filters = {};

    if (values) {
        filters = values;
    }

    this.route.params.subscribe(
        (params: any) => {
            this.page = params['page'];
        }
    );

    console.log('onFilterReceived() firing...');

    let fn = resRecordsData => {
        this.records = resRecordsData;
    };

    this.streamFiltersService.getByFilters(
        this.page - 1, this.pagesize, this.currentStage, this.language = filters['language'], this.location = filters['location'],
        this.zipcode = filters['zip'], this.firstName = filters['firstName'], this.lastName = filters['lastName'],
        this.branch = filters['branch'], fn);
}
我遇到的问题是,随着过滤器的大量启动进入组件,我最终会收到多个网络请求——对于用户来说,屏幕数据会发生多次更改。此外,因为这是异步的,所以有时第一个请求中的一个会最后返回,并且过滤器不会应用到用户看到的屏幕中

完整函数如下所示:

    this.streamFiltersService.getByFilters(
        this.page - 1, this.pagesize, this.currentStage, this.language = filters['language'], this.location = filters['location'],
        this.zipcode = filters['zip'], this.firstName = filters['firstName'], this.lastName = filters['lastName'],
        this.branch = filters['branch'], fn);
    let fn = resRecordsData => {
        this.records = resRecordsData;
    };
public onFilterReceived(values)
{
    let filters = {};

    if (values) {
        filters = values;
    }

    this.route.params.subscribe(
        (params: any) => {
            this.page = params['page'];
        }
    );

    console.log('onFilterReceived() firing...');

    let fn = resRecordsData => {
        this.records = resRecordsData;
    };

    this.streamFiltersService.getByFilters(
        this.page - 1, this.pagesize, this.currentStage, this.language = filters['language'], this.location = filters['location'],
        this.zipcode = filters['zip'], this.firstName = filters['firstName'], this.lastName = filters['lastName'],
        this.branch = filters['branch'], fn);
}
作为后续操作,当我在
onFilterReceived()
内的回调上放置
console.log
时,如下所示:

let fn = async resRecordsData => {
    console.log('records: ', resRecordsData);
    this.records = await resRecordsData;
};
public async onFilterReceived(values)
{
    let filters = {};

    if (values) {
        filters = values;
    }

    this.route.params.subscribe(
        (params: any) => {
            this.page = params['page'];
        }
    );

    console.log('onFilterReceived() firing...');

    let fn = async resRecordsData => {
        await resRecordsData
        .distinctUntilChanged()
        .debounceTime(1000)
        .switchMap( resRecordsData => {
            this.records = resRecordsData;
        });
        console.log('records: ', this.records);
    };

    this.streamFiltersService.getByFilters(
        this.page - 1, this.pagesize, this.currentStage, this.language = filters['language'], this.location = filters['location'],
        this.zipcode = filters['zip'], this.firstName = filters['firstName'], this.lastName = filters['lastName'],
        this.branch = filters['branch'], fn);
}
打印到控制台的内容如下:

records:  {ok: true, status: 200, statusText: "OK", data: Array(1), count: 1}
records:  {ok: true, status: 200, statusText: "OK", data: Array(12), count: 115}
records:  {ok: true, status: 200, statusText: "OK", data: Array(1), count: 1}
records:  {ok: true, status: 200, statusText: "OK", data: Array(1), count: 1}
records:  {ok: true, status: 200, statusText: "OK", data: Array(1), count: 1}
records:  {ok: true, status: 200, statusText: "OK", data: Array(12), count: 115}
records:  {ok: true, status: 200, statusText: "OK", data: Array(12), count: 115}
records:  {ok: true, status: 200, statusText: "OK", data: Array(12), count: 115}
records:  {ok: true, status: 200, statusText: "OK", data: Array(12), count: 115}
records:  {ok: true, status: 200, statusText: "OK", data: Array(12), count: 115}
请注意,因为我应用了一个过滤器,所以正确的值是数组(1)。正如您所看到的,因为这些调用是异步的,所以它们会出现顺序错误。理想情况下,我只需要一个电话,结果如下:

records:  {ok: true, status: 200, statusText: "OK", data: Array(1), count: 1}
根据下面的建议,我尝试将建议的运算符链接到
onFilterReceived()
的回调中,如下所示:

let fn = async resRecordsData => {
    console.log('records: ', resRecordsData);
    this.records = await resRecordsData;
};
public async onFilterReceived(values)
{
    let filters = {};

    if (values) {
        filters = values;
    }

    this.route.params.subscribe(
        (params: any) => {
            this.page = params['page'];
        }
    );

    console.log('onFilterReceived() firing...');

    let fn = async resRecordsData => {
        await resRecordsData
        .distinctUntilChanged()
        .debounceTime(1000)
        .switchMap( resRecordsData => {
            this.records = resRecordsData;
        });
        console.log('records: ', this.records);
    };

    this.streamFiltersService.getByFilters(
        this.page - 1, this.pagesize, this.currentStage, this.language = filters['language'], this.location = filters['location'],
        this.zipcode = filters['zip'], this.firstName = filters['firstName'], this.lastName = filters['lastName'],
        this.branch = filters['branch'], fn);
}
。。。但我最后犯了一个错误:

error_handler.js:60 error:Uncaught(承诺中):TypeError: resRecordsData.distinctUntilChanged不是一个函数


因此,如果我正确理解您的问题:

  • 您可以通过异步回调来维护全局状态(
    this.records
  • http请求被触发,但返回时没有顺序
这与经常重复的情况非常相似

您需要的代码大致如下:

$filterChanges
  .distinctUntilchanged()
  .debounceTime(1000)
  .switchMap(filters => getByFilters(.....))
  .subscribe(records => {
    // modify global state with the records
  });
因此,您首先获取过滤器流及其更改—例如
{page,pagesize,currentStage,language}
。您可能必须为filters对象的
distinctunitChanged
添加
compareFunc
,因为它是非原语

下面是一个粗略的非角度实现示例,可以帮助您:

/*使我们的html过滤器元素可见*/
var carTypeFilter=document.getElementById('cars');
var hornsCheckbox=document.getElementById('horns');
var$carsFilter=Rx.Observable.fromEvent(carTypeFilter,'change')
.map(evt=>({filter:'car',value:evt.target.value}));
var$hornsFilter=Rx.Observable.fromEvent(hornsCheckbox,“更改”)
.map(evt=>({filter:'horns',value:evt.target.checked}));
/*我们希望有一个值包含过滤器的当前逻辑分组*/
var$filtersCombined=Rx.Observable.merge($carsFilter,$hornsFilter)
.scan((allCurrentFilters,currFilterItem)=>{
allCurrentFilters[currFilterItem.filter]=currFilterItem.value;
返回所有当前过滤器;
}, {});
变量$debouncedFilterChanges=$filtersCombined
/*对于DistinctUntil,更改为工作
您需要使用compareFunction进行计算
如果过滤器的所有键:值对都相同
在本例中不打算这样做;它只会过滤掉
单击Frantic后设置过滤器,但只会导致额外的
正在对后端执行请求*/
//.distinctUntilChanged()
/*对于每一个不同的过滤器,都要改变其亮度
我们知道用户已经不再摆弄输入了*/
.去BounceTime(500);
变量$filteredServerResults=$debouncedFilterChanges
.switchMap(filters=>getFilteredData(filters.car,filters.horns));
$filteredServerResults.subscribe(数据=>{
document.getElementById('results').innerText=JSON.stringify(数据);
});
/*
模拟对服务器进行异步调用的模拟函数,响应速度较慢
*/
函数getFilteredData(汽车、喇叭){
//请注意,汽车或喇叭可能未定义
返回Rx.Observable.of(`retrieved value for:${car}-${horns}`)
.delay(1500);//模拟慢速响应,用户可能已经询问了更新的结果
}

JS-Bin
选择一个。。。
沃尔沃汽车
萨博
梅赛德斯
奥迪
汽车
哈肖恩
结果。。。

如果我正确理解您的问题:

  • 您可以通过异步回调来维护全局状态(
    this.records
  • http请求被触发,但返回时没有顺序
这与经常重复的情况非常相似

您需要的代码大致如下:

$filterChanges
  .distinctUntilchanged()
  .debounceTime(1000)
  .switchMap(filters => getByFilters(.....))
  .subscribe(records => {
    // modify global state with the records
  });
因此,您首先获取过滤器流及其更改—例如
{page,pagesize,currentStage,language}
。您可能必须为filters对象的
distinctunitChanged
添加
compareFunc
,因为它是非原语

下面是一个粗略的非角度实现示例,可以帮助您:

/*使我们的html过滤器元素可见*/
var carTypeFilter=document.getElementById('cars');
var hornsCheckbox=document.getElementById('horns');
var$carsFilter=Rx.Observable.fromEvent(carTypeFilter,'change')
.map(evt=>({filter:'car',value:evt.target.value}));
var$hornsFilter=Rx.Observable.fromEvent(hornsCheckbox,“更改”)
.map(evt=>({filter:'horns',value:evt.target.checked}));
/*我们希望有一个值包含过滤器的当前逻辑分组*/
var$filtersCombined=Rx.Observable.merge($carsFilter,$hornsFilter)
.scan((allCurrentFilters,currFilterItem)=>{
allCurrentFilters[currFilterItem.filter]=currFilterItem.value;
返回所有当前过滤器;
}, {});
变量$debouncedFilterChanges=$filtersCombined
/*对于DistinctUntil,更改为工作
您需要使用compareFunction进行计算
如果过滤器的所有键:值对都相同
在本例中不打算这样做;它只会过滤掉
单击Frantic后设置过滤器,但只会导致额外的
正在对后端执行请求*/
//.distinctUntilChanged()
/*对于每一个不同的过滤器,都要改变其亮度
我们知道用户已经停止