Node.js和Express:正确履行承诺

问题描述

我有一个简单的node.js应用程序,它使用systeminformation包检查了当前树莓派温度,并且还检查了public ip,因为我是使用动态dns公开我的pi。它通过明确的get请求在浏览器中显示。我还将PM2用于流程管理并始终保持app.js正常运行。

每当有一个对“ /”的获取请求时,我想将时间戳,IP和温度记录到log.txt中。下面的代码完成了ALMOST。它会在浏览器中显示温度和IP,并在将正确的时间戳和IP记录到“ log.txt”时,温度(存储在变量“ temp”中)始终显示为“ undefined”。

const si = require('systeminformation');
const pip4 = require('public-ip');
const express = require('express');
const app = express();
const port = 3389;
const fs = require('fs');
let temp;

app.listen(port,() => {
    console.log(`Server running on port ${port}`);
});

app.get("/",(req,res,next) => {
  
  //get cpu temperature and store it in ${temp}
  si.cpuTemperature()
      .then(data => {temp = data; })
      .catch(error => console.error(error));
  
  //get public IP and store it in ${ip}    
  (async () => {
    let ip = (await pip4.v4());
  
  const text = `${Date()} from IP: ${ip} and core temp: ${temp}` + '\r\n';

  //append timestamp and IP info to log.txt
  fs.appendFile('./log/log.txt',text,(err) => {
    if (err) throw err;
    console.log('Successfully logged request.');
  });
  
  //display cpu temperature and IP in the browser
  setTimeout(() => {
    res.json({
      temp,ip
    });
  },250);

  })();

});

http响应有效并显示温度和IP:

{"temp":{"main":37.485,"cores":[],"max":37.485},"ip":"x.x.x.x"}

但是log.txt中记录的临时条目始终未定义:

Wed Aug 26 2020 13:07:30 GMT+0200 (Central European Summer Time) from IP: x.x.x.x and core temp: undefined

我了解这是由于未兑现的承诺,但我似乎找不到合适的解决方法...

解决方法

让您的处理者完全async;不必担心混合和匹配.then()

const si = require("systeminformation");
const pip4 = require("public-ip");
const express = require("express");
const app = express();
const port = 3389;
const fs = require("fs");

app.listen(port,() => {
  console.log(`Server running on port ${port}`);
});

app.get("/",async (req,res) => {
  const temp = await si.cpuTemperature();
  const ip = await pip4.v4();
  const text = `${Date()} from IP: ${ip} and core temp: ${temp}\r\n`;
  fs.appendFile("./log/log.txt",text,(err) => {
    if (err) console.error(`Logging: ${err}`);
  });
  res.json({ temp,ip });
});

您可以通过并行进行IP和CPU温度查询来加快速度:

app.get("/",res) => {
  const [temp,ip] = await Promise.all([si.cpuTemperature(),pip4.v4()]);
  const text = `${Date()} from IP: ${ip} and core temp: ${temp}\r\n`;
  fs.appendFile('./log/log.txt',(err) => {
    if (err) console.error(`Logging: ${err}`);
  });
  res.json({temp,ip});
});

但这两个都缺少错误处理。

编辑:另一种变体也记录为JSON,以正确表示(嘿)所有对象:

app.get("/",pip4.v4()]);
  const logData = JSON.stringify({date: Date(),ip,temp}) + '\r\n';
  fs.appendFile('./log/log.txt',logData,ip});
});