HarmonyOS鸿蒙Next中如何取消RCP正在进行的网络请求

HarmonyOS鸿蒙Next中如何取消RCP正在进行的网络请求

场景:输入框内容发生改变时,请求网络接口数据

Q:如何先把上一个没有完成的请求结束?

目前写了一个公共的方法,cancel()方法应该写在哪个位置,我看文档写到了then回调里了,觉得是不是不太对啊?close()需不需要这样写

//外部调用
private txtChanged() {
  HttpUtil.rcp_request(this.context, 'POST', url, paraDict).then((data: string) => { 
    console.log('result = ', data)  
  })
}

//HttpUtil.ets
//请求
static rcp_request(context: Context, method: string, url: string, params: Record<string, string | number>): Promise<string> {
  return new Promise((resolve) {

    let urlArray: string[] = url.split('/')
    let urlKey = urlArray[urlArray.length - 1]

    const session = rcp.createSession()

    let back = HttpUtil.getRequestSign(context, params, urlKey)
    let postContent: rcp.Form = HttpUtil.strToFormFileds(context, back)

    let req = new rcp.Request(url, method, undefined, postContent);
    session.fetch(req).then((response) => {
      let result = response.toJSON()
      let str = response.toString()
      console.info(`Succeeded in getting the response ${response}`);
      session.close()
      resolve(str ?? '')
    }).catch((err: BusinessError) => {
      console.error(`err: err code is ${err.code}, err message is ${JSON.stringify(err)}`);
      session.close()
    });
  })

}

更多关于HarmonyOS鸿蒙Next中如何取消RCP正在进行的网络请求的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

在工具类中维护当前活跃的会话实例,每次发起新请求前取消上一个请求:

// HttpUtil.ets
static currentSession: rcp.Session | null = null;
static currentRequest: rcp.Request | null = null;

static cancelPreviousRequest() {
  if (this.currentSession && this.currentRequest) {
    try {
      this.currentSession.cancel([this.currentRequest]);
      this.currentSession.close();
    } catch (error) {
      console.error('Cancel request failed:', error);
    }
  }
}

在输入框变更事件中优先取消旧请求:

// 外部调用
private txtChanged() {
  HttpUtil.cancelPreviousRequest();
  HttpUtil.rcp_request(this.context, 'POST', url, paraDict).then((data: string) => {
    console.log('result = ', data);
  });
}

更多关于HarmonyOS鸿蒙Next中如何取消RCP正在进行的网络请求的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在响应处理之前或之后无法取消请求,可能是由于请求的生命周期或事件处理顺序导致的。比如:在请求已经完成或失败的情况下,请求无法再被取消。

  • 取消所有网络请求:如果不需要指定特定的请求,可以直接调用cancel取消所有正在进行的网络请求:
import { rcp } from '@kit.RemoteCommunicationKit';
const session = rcp.createSession();
session.cancel();
  • 取消特定的网络请求:如果需要取消特定的请求,可以在调用cancel时传入相应的请求对象:
import { rcp } from '@kit.RemoteCommunicationKit';
const session = rcp.createSession();
let request = new rcp.Request("https://www.example.com");
session.fetch(request).then((response: rcp.Response) => {
  console.info(`The response code is ${response.statusCode}`);
}).catch((err: BusinessError) => {
  if(err){
    console.error(`Error code is ${err.code}`);
  }
});
session.cancel(request);

在HarmonyOS Next中取消RPC网络请求,使用HttpTaskabort()方法。

示例代码:

import http from '@ohos.net.http';

let httpTask: http.HttpTask = http.createHttp().request(
  "https://example.com",
  { method: 'GET' },
  (err, data) => {}
);

// 取消请求
httpTask.abort();

关键点:

  1. 保存request()返回的HttpTask对象
  2. 调用abort()时需确保请求未完成
  3. 取消后触发回调函数的err参数会包含终止信息

在HarmonyOS Next中取消RCP网络请求的正确做法是在发起新请求前取消上一个未完成的请求。针对你的代码,建议修改如下:

  1. 在HttpUtil类中维护一个sessionMap,存储每个请求的session实例:
private static sessionMap: Map<string, rcp.Session> = new Map();
  1. 修改rcp_request方法,在发起新请求前取消同urlKey的旧请求:
static rcp_request(context: Context, method: string, url: string, params: Record<string, string | number>): Promise<string> {
  return new Promise((resolve) => {
    let urlArray: string[] = url.split('/')
    let urlKey = urlArray[urlArray.length - 1]
    
    // 取消之前的请求
    if (this.sessionMap.has(urlKey)) {
      this.sessionMap.get(urlKey)?.close();
    }

    const session = rcp.createSession()
    this.sessionMap.set(urlKey, session);

    // 剩余代码保持不变...
  })
}
  1. 在then和catch回调中移除sessionMap中的记录:
session.fetch(req).then((response) => {
  // ...原有代码
  this.sessionMap.delete(urlKey);
}).catch((err: BusinessError) => {
  // ...原有代码
  this.sessionMap.delete(urlKey);
});

这种方式可以确保每次新请求都会自动取消同urlKey的未完成请求,避免请求堆积。close()调用是必要的,它用于释放网络资源。

回到顶部