HarmonyOS 鸿蒙Next中Promise reject之后,Promise中的代码还在运行
HarmonyOS 鸿蒙Next中Promise reject之后,Promise中的代码还在运行
由于想在组件的aboutToDisappear中取消正在执行的Promise避免资源的浪费
cancelPromise: () => void = () => {}
aboutToAppear(): void {
new Promise<string>(async (resolve, reject) => {
this.cancelPromise = () => {
reject({ code: -1, message: "cancel promise" } as BusinessError<undefined>);
}
let i = 0
while (i < 1000) {
i++
await sleep(100)
Logger.debug(i.toString())
}
resolve(i.toString())
}).then((str) => {
Logger.info(str)
}).catch((e: BusinessError) => {
Logger.error(e.message)
})
}
aboutToDisappear(): void {
this.cancelPromise()
}
结果发现退出该页面后, Promise中的while代码还在执行!
引入一个标志位来判断:
new Promise<string>(async (resolve, reject) => {
let isPending = true
this.cancelPromise = () => {
reject({ code: -1, message: "cancel promise" } as BusinessError<undefined>);
isPending = false
}
let i = 0
while (i < 1000 && isPending) {
i++
await sleep(100)
Logger.debug(i.toString())
}
resolve(i.toString())
}).then((str) => {
Logger.info(str)
}).catch((e: BusinessError) => {
Logger.error(e.message)
})
ok退出页面后,Promise中的代码没在执行了。
那如果Promise执行的是一个http请求呢?http还没有响应就退出该页面,那该如何去取消这个promise?
封装一个createCancellablePromise方法,ts代码:
export function createCancellablePromise<T>(executor: ((resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: any) => void,eventId:string,isPending:() =>boolean) => void): Promise<T>{
let _resolve: any = null;
let _reject: any = null;
// 创建 Promise 并绑定事件监听
return new Promise<T>((resolve, reject) => {
const eventId: string = util.generateRandomUUID(true);
let pending = true
const isPending = () => {return pending}
// 注册一次性事件监听
emitter.once(eventId, () => {
reject({code:-1,message:"cancel promise"} as BusinessError<undefined>);
pending = false
});
_resolve = (value: T) => {
emitter.off(eventId)
resolve(value);
pending = false
};
_reject = (reason?: any) => {
emitter.off(eventId)
reject(reason);
pending = false
};
// 执行主任务
executor(_resolve, _reject,eventId,isPending);
});
}
组件页面代码:
cancelPromise: () => void = () => {}
async rcpGetRepositories(cancelEventId: string): Promise<Repositories> {
const req =
new rcp.Request(`https://api.github.com/search/repositories?q=node.js+language:javascript&sort=stars`, 'GET')
//收到取消promise的事件,则取消指定或正在进行的会话请求
emitter.once(cancelEventId, () => {
session.cancel(req)
})
let response = await session.fetch(req)
if (response.statusCode == 200 && response.toJSON()) {
return response.toJSON() as Repositories
} else {
return Promise.reject({ code: -2, message: "response is undefined" } as BusinessError<undefined>);
}
}
aboutToAppear(): void {
createCancellablePromise<Repositories>(async (resolve, reject, cancelEventId, isPending) => {
this.cancelPromise = () => {
if (isPending()) {
emitter.emit(cancelEventId)
}
}
//http请求数据
this.rcpGetRepositories(cancelEventId).then((rep) => {
Logger.info(`rcpGetRepositories then ${rep}`)
resolve(rep)
}).catch((e: BusinessError) => {
Logger.error(`rcpGetRepositories catch ${e.message}`)
reject(e)
})
}).then((repositories) => {
this.repositories = repositories
}).catch((e: BusinessError) => {
Logger.error(e.message)
})
}
aboutToDisappear(): void {
this.cancelPromise()
}
更多关于HarmonyOS 鸿蒙Next中Promise reject之后,Promise中的代码还在运行的实战教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next中,当Promise被reject后,Promise内的代码仍会继续执行直到完成。这是由于Promise的执行机制决定的,reject仅改变Promise状态并触发catch回调,但不会中断已开始执行的代码。要停止后续执行,需要在reject后手动添加return或通过条件判断终止逻辑。示例:
new Promise((resolve, reject) => {
reject('error');
console.log('这行仍会执行');
// 需自行终止
return;
}).catch(err => {});
更多关于HarmonyOS 鸿蒙Next中Promise reject之后,Promise中的代码还在运行的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
这是一个关于Promise取消机制在HarmonyOS中的实现问题。根据代码分析,您已经正确理解了Promise的基本行为:调用reject()并不会中断正在执行的Promise代码,只是改变了Promise的状态。
对于HTTP请求的取消,您的解决方案是正确的。关键点在于:
- 使用session.cancel()来真正终止网络请求
- 通过事件机制(emitter)来触发取消操作
- 使用isPending标志位来避免不必要的取消操作
这种实现方式符合Promise的设计原则,因为:
- 原生Promise没有内置取消机制
- 需要开发者自行实现取消逻辑
- 网络请求需要调用特定API(session.cancel)才能真正终止
您的createCancellablePromise封装很好地解决了这个问题,这种模式在HarmonyOS开发中是推荐的实践方式。
对于其他异步操作,也可以采用类似的模式:在取消时不仅调用reject,还要调用具体的终止API(如网络请求的cancel、定时器的clear等)。