fix(napi): async task finally is not called (#2824)

This commit is contained in:
LongYinan 2025-08-01 15:05:08 +08:00 committed by GitHub
parent e44329a059
commit e175512d43
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 62 additions and 4 deletions

View File

@ -31,15 +31,19 @@ impl<'a, T: Task> ScopedTask<'a> for T {
type JsValue = T::JsValue;
fn compute(&mut self) -> Result<Self::Output> {
Task::compute(self)
T::compute(self)
}
fn resolve(&mut self, env: &'a Env, output: Self::Output) -> Result<Self::JsValue> {
Task::resolve(self, Env::from_raw(env.raw()), output)
T::resolve(self, Env::from_raw(env.raw()), output)
}
fn reject(&mut self, env: &'a Env, err: Error) -> Result<Self::JsValue> {
Task::reject(self, Env::from_raw(env.raw()), err)
T::reject(self, Env::from_raw(env.raw()), err)
}
fn finally(self, env: Env) -> Result<()> {
T::finally(self, env)
}
}

View File

@ -394,6 +394,8 @@ Generated by [AVA](https://avajs.dev).
export declare function asyncResolveArray(inner: number): Promise<unknown[]>
export declare function asyncTaskFinally(inner: object): Promise<void>
export declare function asyncTaskOptionalReturn(): Promise<number | null>
export declare function asyncTaskReadFile(path: string): Promise<Buffer>

View File

@ -79,6 +79,7 @@ import {
withAbortController,
asyncTaskReadFile,
asyncTaskOptionalReturn,
asyncTaskFinally,
asyncResolveArray,
asyncMultiTwo,
bigintAdd,
@ -1342,7 +1343,7 @@ test('should be able to return object from shared crate', (t) => {
const AbortSignalTest =
typeof AbortController !== 'undefined' ? test : test.skip
AbortSignalTest('async task without abort controller', async (t) => {
test('async task without abort controller', async (t) => {
t.is(await withoutAbortController(1, 2), 3)
})
@ -1394,6 +1395,16 @@ test('abort signal should be able to reuse with different tasks', async (t) => {
})
})
test('async task finally must be called', async (t) => {
const obj = {
finally: false,
resolve: false,
}
await asyncTaskFinally(obj)
t.is(obj.finally, true)
t.is(obj.resolve, true)
})
const BigIntTest = typeof BigInt !== 'undefined' ? test : test.skip
BigIntTest('BigInt add', (t) => {

View File

@ -137,6 +137,7 @@ export const asyncMultiTwo = __napiModule.exports.asyncMultiTwo
export const asyncPlus100 = __napiModule.exports.asyncPlus100
export const asyncReduceBuffer = __napiModule.exports.asyncReduceBuffer
export const asyncResolveArray = __napiModule.exports.asyncResolveArray
export const asyncTaskFinally = __napiModule.exports.asyncTaskFinally
export const asyncTaskOptionalReturn = __napiModule.exports.asyncTaskOptionalReturn
export const asyncTaskReadFile = __napiModule.exports.asyncTaskReadFile
export const asyncTaskVoidReturn = __napiModule.exports.asyncTaskVoidReturn

View File

@ -182,6 +182,7 @@ module.exports.asyncMultiTwo = __napiModule.exports.asyncMultiTwo
module.exports.asyncPlus100 = __napiModule.exports.asyncPlus100
module.exports.asyncReduceBuffer = __napiModule.exports.asyncReduceBuffer
module.exports.asyncResolveArray = __napiModule.exports.asyncResolveArray
module.exports.asyncTaskFinally = __napiModule.exports.asyncTaskFinally
module.exports.asyncTaskOptionalReturn = __napiModule.exports.asyncTaskOptionalReturn
module.exports.asyncTaskReadFile = __napiModule.exports.asyncTaskReadFile
module.exports.asyncTaskVoidReturn = __napiModule.exports.asyncTaskVoidReturn

View File

@ -467,6 +467,7 @@ module.exports.asyncMultiTwo = nativeBinding.asyncMultiTwo
module.exports.asyncPlus100 = nativeBinding.asyncPlus100
module.exports.asyncReduceBuffer = nativeBinding.asyncReduceBuffer
module.exports.asyncResolveArray = nativeBinding.asyncResolveArray
module.exports.asyncTaskFinally = nativeBinding.asyncTaskFinally
module.exports.asyncTaskOptionalReturn = nativeBinding.asyncTaskOptionalReturn
module.exports.asyncTaskReadFile = nativeBinding.asyncTaskReadFile
module.exports.asyncTaskVoidReturn = nativeBinding.asyncTaskVoidReturn

View File

@ -355,6 +355,8 @@ export declare function asyncReduceBuffer(buf: Buffer): Promise<number>
export declare function asyncResolveArray(inner: number): Promise<unknown[]>
export declare function asyncTaskFinally(inner: object): Promise<void>
export declare function asyncTaskOptionalReturn(): Promise<number | null>
export declare function asyncTaskReadFile(path: string): Promise<Buffer>

View File

@ -17,6 +17,10 @@ impl napi::Task for DelaySum {
fn resolve(&mut self, _env: napi::Env, output: Self::Output) -> Result<Self::JsValue> {
Ok(output)
}
fn finally(self, _env: Env) -> Result<()> {
Ok(())
}
}
#[napi]
@ -122,3 +126,35 @@ pub fn async_resolve_array(inner: u32) -> AsyncTask<AsyncResolveArray> {
inner: inner as usize,
})
}
pub struct AsyncTaskFinally {
inner: ObjectRef,
}
#[napi]
impl Task for AsyncTaskFinally {
type Output = ();
type JsValue = ();
fn compute(&mut self) -> Result<Self::Output> {
Ok(())
}
fn resolve(&mut self, env: Env, _output: Self::Output) -> Result<Self::JsValue> {
let mut obj = self.inner.get_value(&env)?;
obj.set("resolve", true)?;
Ok(())
}
fn finally(self, env: Env) -> Result<()> {
let mut obj = self.inner.get_value(&env)?;
obj.set("finally", true)?;
self.inner.unref(&env)?;
Ok(())
}
}
#[napi]
pub fn async_task_finally(inner: ObjectRef) -> AsyncTask<AsyncTaskFinally> {
AsyncTask::new(AsyncTaskFinally { inner })
}