[njs] Fixed execution of async function in synchronous context.
Dmitry Volyntsev
xeioex at nginx.com
Fri Dec 3 13:57:20 UTC 2021
details: https://hg.nginx.org/njs/rev/ed1756875eb5
branches:
changeset: 1758:ed1756875eb5
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Fri Dec 03 13:55:22 2021 +0000
description:
Fixed execution of async function in synchronous context.
The bug was introduced in 92d10cd761e2 (0.7.0).
diffstat:
src/njs_async.c | 6 ++++++
src/test/njs_unit_test.c | 16 ++++++++++++++++
test/js/async_promise.t.js | 20 ++++++++++++++++++++
3 files changed, 42 insertions(+), 0 deletions(-)
diffs (73 lines):
diff -r cd87a113829d -r ed1756875eb5 src/njs_async.c
--- a/src/njs_async.c Fri Dec 03 13:55:12 2021 +0000
+++ b/src/njs_async.c Fri Dec 03 13:55:22 2021 +0000
@@ -37,6 +37,9 @@ njs_async_function_frame_invoke(njs_vm_t
ret = njs_function_call(vm, njs_function(&capability->resolve),
&njs_value_undefined, retval, 1, &vm->retval);
+ } else if (ret == NJS_AGAIN) {
+ ret = NJS_OK;
+
} else if (ret == NJS_ERROR) {
if (njs_is_memory_error(vm, &vm->retval)) {
return NJS_ERROR;
@@ -116,6 +119,9 @@ njs_await_fulfilled(njs_vm_t *vm, njs_va
njs_async_context_free(vm, ctx);
+ } else if (ret == NJS_AGAIN) {
+ ret = NJS_OK;
+
} else if (ret == NJS_ERROR) {
if (njs_is_memory_error(vm, &vm->retval)) {
return NJS_ERROR;
diff -r cd87a113829d -r ed1756875eb5 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Fri Dec 03 13:55:12 2021 +0000
+++ b/src/test/njs_unit_test.c Fri Dec 03 13:55:22 2021 +0000
@@ -21024,6 +21024,22 @@ static njs_unit_test_t njs_externals_te
"$r.subrequest('b')"
".then(select => cb($r, select))"),
njs_str("2") },
+
+ { njs_str("function pr(x) { return new Promise(resolve => {resolve(x + ':pr')}); };"
+ "Promise.all(['a', 'b', 'c'].map(async (v) => {"
+ " return await pr(v + ':async');"
+ "}))"
+ ".then(v => $r.retval(v))"),
+ njs_str("a:async:pr,b:async:pr,c:async:pr") },
+
+ { njs_str("function pr(x) { return new Promise(resolve => {resolve(x + ':pr')}); };"
+ "Promise.all(['a', 'b', 'c'].map(async (v) => {"
+ " let r = await pr(v + ':async');"
+ " let r2 = await pr(r + ':async2');"
+ " return r2 + ':r';"
+ "}))"
+ ".then(v => $r.retval(v))"),
+ njs_str("a:async:pr:async2:pr:r,b:async:pr:async2:pr:r,c:async:pr:async2:pr:r") },
};
diff -r cd87a113829d -r ed1756875eb5 test/js/async_promise.t.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/js/async_promise.t.js Fri Dec 03 13:55:22 2021 +0000
@@ -0,0 +1,20 @@
+/*---
+includes: [compareArray.js]
+flags: [async]
+---*/
+
+let stages = [];
+
+function pr(x) { return new Promise(resolve => {resolve(x)}); }
+
+pr(10)
+.then(async (v) => {
+ stages.push("then before");
+ let y = await pr(22);
+ stages.push(`then ${v} ${y}`);
+ return v + y;
+})
+.then(v => stages.push(`then2 ${v}`))
+.catch(e => $DONOTEVALUATE())
+.then(v => assert.compareArray(stages, ['then before', 'then 10 22', 'then2 32']))
+.then($DONE, $DONE);
More information about the nginx-devel
mailing list