Node.js 在Promise中运行异步函数的正确方法
我正在做一个测试应用程序使用。我试图使每个Node.js 在Promise中运行异步函数的正确方法,node.js,asynchronous,Node.js,Asynchronous,我正在做一个测试应用程序使用。我试图使每个都等待上一个函数完成。我遇到的问题是,我在其中运行的函数也是承诺,因此下一个然后在函数完成之前运行 const si = require('systeminformation'); var cpuObj; function initCPU() { return new Promise(resolve => { si.cpu() .then(data => cpuObj = data) .catch(
都等待上一个函数完成。我遇到的问题是,我在其中运行的函数也是承诺,因此下一个然后在函数完成之前运行
const si = require('systeminformation');
var cpuObj;
function initCPU() {
return new Promise(resolve => {
si.cpu()
.then(data => cpuObj = data)
.catch(err => console.log(err))
.then(() => {
setTimeout(() => console.log("timer"), 3000);
})
.then(() => {
si.cpuTemperature().then(data => console.log(data));
})
.then(() => {
console.log("here");
});
});
}
function test() {
console.log(cpuObj);
}
initCPU().then(() => {
test();
});
输出:
here
{ main: -1, cores: [], max: -1 }
timer
预期产出:
{ main: -1, cores: [], max: -1 }
timer
here
需要解决的几个问题:
- 不返回承诺,所以你需要承诺并返回它
- 通过从每个延续中返回承诺,而不是尝试在其他延续中(即
then()
内部的then()
)链接延续,来扁平化链
- 不要用承诺构造函数包装延续链,因为该链本身已经是一个承诺,只需直接返回它即可。这是值得考虑的
- 不要使用globals,因为它会使
initCPU()
重新进入不再安全。在第一个调用返回的承诺解析之前多次调用initCPU()
,否则将导致意外行为。相反,使用适当的范围传递值,在本例中是函数本身
- 允许错误传播到调用方,并让调用方决定如何处理错误。不要处理
initCPU()
中的错误,除非您希望使用回退并继续向调用者提供有意义的数据
const si=require('systeminformation');
const delay=ms=>newpromise(resolve=>{setTimeout(resolve,ms);});
函数initCPU(){
//使用局部作用域,而不是全局作用域
让cpuObj;
//直接退还此承诺链
返回si.cpu()
。然后(数据=>{
cpuObj=数据;
//把承诺还给锁链
返回延迟(3000);
})
//让调用者处理错误
//.catch(err=>console.log(err))
//把你的链条弄平
.然后(()=>{
console.log('timer');
//把承诺还给锁链
返回si.cputtemperature();
})
//把你的链条弄平
。然后(数据=>{
控制台日志(数据);
console.log('here');
//将数据传递给调用者
返回cpuObj;
});
}
功能测试(cpuObj){
//从initCPU()的上一个延续中接收
console.log(cpuObj);
}
initCPU()
.然后(测试)
//处理来自调用者的错误
.catch(错误=>{
控制台日志(err);
});
如果您只想立即查询cpu
对象,并在3秒钟后查询cputtemperature
,我将使用以下方法执行类似操作:
别上当!计时器的用途是什么?只是测试它是否等待
// default to 3 seconds, allow it to be configurable
function initCPU(ms = 3000) {
return Promise.all([
si.cpu(),
delay(ms).then(() => si.cpuTemperature())
]).then(([cpu, cpuTemperature]) => ({
cpu,
cpuTemperature
}));
}
function test (obj) {
console.log(obj.cpu);
console.log(obj.cpuTemperature);
}
initCPU()
.then(test)
.catch(err => {
console.log(err);
});