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);
  });