node.js - Nodejs 中的等待、链式承诺和流控制
问题描述
我想一个接一个地执行函数,使用上一个调用返回的值进入下一个。
我使用以下代码使其工作:
var i = 0;
async function testn() {
console.log('%s -> test%s (i = %s)', new Date(), i+1, i++);
setTimeout(console.log, timeout1, ' value of i in test%s : ', i, i);
console.log('%s <- test%s (i = %s)', new Date(), i, i);
return {result: 0};
}
async function wrapIt() {
await testn()
.then(await testn())
.then(await testn())
.catch((error) => {
console.log('caught %s', error);
})
.finally(() => {
console.log('finally %s', i);
})
}
wrapIt();
这是输出:
2021-07-14T12:23:56.677Z -> test1 (i = 0)
2021-07-14T12:23:56.678Z <- test1 (i = 1)
2021-07-14T12:23:56.678Z -> test2 (i = 1)
2021-07-14T12:23:56.678Z <- test2 (i = 2)
2021-07-14T12:23:56.678Z -> test3 (i = 2)
2021-07-14T12:23:56.678Z <- test3 (i = 3)
finally 3
value of i in test1 : 1
value of i in test2 : 2
value of i in test3 : 3
如果我使用显式 Promises 而不是隐式返回 Promise 的async关键字,则行为会发生变化(查看两次调用 testn() 之间的延迟)。
var i = 0;
var timeout1 = 5000;
var timeout2 = 1000;
async function testn() {
return new Promise(function (resolve,reject) {
console.log('%s -> test%s (i = %s)', new Date(), i+1, i++);
setTimeout(console.log, timeout1, ' value of i in test%s : ', i, i);
console.log('%s <- test%s (i = %s)', new Date(), i, i);
setTimeout(() => {resolve({result: 0})}, timeout2);
})
}
async function wrapIt() {
await testn()
.then(await testn())
.then(await testn())
.catch((error) => {
console.log('caught %s', error);
})
.finally(() => {
console.log('finally %s', i);
})
}
这是输出:
2021-07-14T12:20:27.670Z -> test1 (i = 0)
2021-07-14T12:20:27.671Z <- test1 (i = 1)
2021-07-14T12:20:27.671Z -> test2 (i = 1)
2021-07-14T12:20:27.671Z <- test2 (i = 2)
2021-07-14T12:20:28.672Z -> test3 (i = 2)
2021-07-14T12:20:28.672Z <- test3 (i = 3)
finally 3
value of i in test1 : 1
value of i in test2 : 2
value of i in test3 : 3
为什么延迟1 s。仅在第 2 次和第 3 次调用之间有效,而不在第 1 次和第 2 次调用之间有效?
解决方案
如果您的问题与 无关setTimeout
,您可以通过await
以下方式使用类似同步函数调用的值:
async function testn(arg) {
console.log(arg++);
return arg;
}
async function wrapIt() {
const res1 = await testn(0);
const res2 = await testn(res1);
const res3 = await testn(res2);
console.log('finally %s', res3);
}
wrapIt();
推荐阅读
- node.js - 如何在Nodejs(微服务)中将大量数据(100万大小的对象数组)从一个服务发送到另一个服务?
- python - 计算概率描述性统计的正确方法
- wordpress - 如何检查自定义字段是否具有特定值
- json - 单击父级时如何仅显示嵌套元素?- 反应
- c - 为什么这个不区分大小写的 strstr() 函数版本不起作用?
- angular - waitForAngularEnable(true) 不起作用 - ScriptTimeoutError:脚本超时:未收到结果
- excel - 如何使“编辑链接”VBA 代码运行得更快?
- python - 安装两个不同版本的CUDA后如何切换CUDA版本?
- c++ - C++ 中的函数是否有任何默认返回类型?
- sql - SQL Page Life Expectancy cntr_value 是秒还是毫秒?