【问题标题】:Nodejs & Express: properly resolve a promiseNodejs & Express:正确解决一个承诺
【发布时间】:2020-12-15 04:26:50
【问题描述】:

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

每次有对“/”的获取请求时,我想将时间戳、IP 和温度记录到 log.txt。下面的代码几乎可以解决问题。它在浏览器中显示温度和 IP,并且在将正确的时间戳和 IP 记录到“log.txt”时,温度(存储在变量“temp”中)始终显示为“未定义”。

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

我知道这是由于一个未解决的承诺,但我似乎无法找到正确解决它的方法...

【问题讨论】:

    标签: node.js express async-await raspberry-pi pm2


    【解决方案1】:

    使您的处理程序完全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("/", async (req, 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', text, (err) => {
        if (err) console.error(`Logging: ${err}`);
      });
      res.json({temp, ip});
    });
    

    不过,这两个都缺少错误处理。

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

    app.get("/", async (req, res) => {
      const [temp, ip] = await Promise.all([si.cpuTemperature(), pip4.v4()]);
      const logData = JSON.stringify({date: Date(), ip, temp}) + '\r\n';
      fs.appendFile('./log/log.txt', logData, (err) => {
        if (err) console.error(`Logging: ${err}`);
      });
      res.json({temp, ip});
    });
    

    【讨论】:

    • 嘿,@AKX,尝试了您的第二个建议,看起来不错,但现在它记录了 'Wed Aug 26 2020 14:00:49 ... from IP: ... and core temp: [ log.txt 中的对象对象]'。它通过http正确显示温度。
    • 温度返回值可能不是一个裸字符串...
    • 太棒了,做到了。非常感谢 - 它也帮助我理解了更好的处理承诺。非常感谢!
    猜你喜欢
    • 2019-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-26
    相关资源
    最近更新 更多