jjzjj

javascript - 异步函数在 while 循环中不立即产生结果

coder 2025-01-15 原文

我是 nodejs 的新手,我所做的是将 LCD 面板和 4x4 薄膜矩阵键盘连接到 Raspberry Pi,并使用 Node.js 对它们进行编程。我想要实现的是,只要按下一个键,它就应该立即显示在 LCD 面板上,而当我按下 # 时,它应该停止接受输入。

为此我使用了软件包 LCD https://www.npmjs.com/package/lcd和 RPIO https://github.com/jperkin/node-rpio由于我必须不断检查用户输入,所以我将用于获取输入的代码放入 while 循环中,并在其中编写了 print 语句,这就是问题所在。当我按键盘上的某个键时,LCD 面板不显示任何字符,但当我按 # 时,程序退出,所有字符都显示在 LCD 面板上。

我写的代码如下。

var rpio = require('rpio');
var Lcd = require('lcd'),//This is asynchronous function
    lcd = new Lcd({
        rs: 18,
        e: 23,
        data: [24, 17, 27, 22],
        cols: 8,
        rows: 2
    });
var matrix=[[1,2,3,'A'],
            [4,5,6,'B'],
            [7,8,9,'C'],
            ['*',0,'#','D']]
var row=[37,35,33,31];
var col=[29,23,40,38];
for (var i = 0; i < 4; i++) {
    rpio.open(col[i], rpio.OUTPUT, rpio.HIGH);
}
for (var i = 0; i < 4; i++) {
    rpio.open(row[i], rpio.INPUT, rpio.PULL_UP);
}
var code="";
var comeout=0;
lcd.on('ready', function() {
    lcd.setCursor(0, 0);
    //start of keypad code
    while(true){
        for (var j = 0; j < 4; j++) {
            rpio.write(col[j],rpio.LOW);
            for (var i = 0; i < 4; i++) {
                if(rpio.read(row[i])==0){
                    console.log(matrix[i][j]);
                    lcd.print(matrix[i][j]);
                    if(matrix[i][j]=='#'){
                        comeout=1;
                        break;
                    }
                    while(rpio.read(row[i])==0);
                }
            }
            if(comeout==1)
                break;
            else
                rpio.write(col[j],rpio.HIGH);
        }
        if(comeout==1)
            break;
    }
    //end of keypad code
});

// If ctrl+c is hit, free resources and exit.
process.on('SIGINT', function() {
    lcd.clear();
    lcd.close();
    process.exit();
});

任何帮助将不胜感激。谢谢。

最佳答案

根据上面与@Thomas 的讨论,我建议您使用 setImediate 调用来模拟 while(true) 循环,在其中请求矩阵并执行 LCD 。打印。这是因为 LCD.print 将操作添加到 javascripts 事件队列。但是事件队列的操作被阻塞,直到实际操作完成。只要您处于 while(true) 循环中,它就永远不会完成。

因此您必须结束事件操作并赋予事件循环控制权,事件循环依次执行打印命令。但同时你必须确保在不按“#”键的情况下再次扫描按键矩阵。

这是一个例子:

lcd.on('ready', function() 
{
  lcd.setCursor(0, 0);
  setImediate(
  function scanMatrix()
  {
    for (var j = 0; j < 4; j++) 
    {
      rpio.write(col[j],rpio.LOW);
      for (var i = 0; i < 4; i++) 
      {
        if(rpio.read(row[i])==0)
        {
          console.log(matrix[i][j]);
          lcd.print(matrix[i][j]);
          if(matrix[i][j]!='#')
          {
            setImmediate(scanMatrix);
          }
          while(rpio.read(row[i])==0);
        }
      }
      rpio.write(col[j],rpio.HIGH);
    }
  });
});

代码没有测试,因为我这里没有raspi。它应该让您了解如何解决问题。

一个非常酷的 ;-) 解决方案是向键矩阵添加一个微 Controller (MSP430,...)。 MC 扫描矩阵并通过 SPI 或 I2C 将按键传输到 raspi。 ....好吧好吧别打我;-)

关于javascript - 异步函数在 while 循环中不立即产生结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41529688/

有关javascript - 异步函数在 while 循环中不立即产生结果的更多相关文章

  1. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  2. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  3. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  4. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  5. 报告回顾丨模型进化狂飙,DetectGPT能否识别最新模型生成结果? - 2

    导读语言模型给我们的生产生活带来了极大便利,但同时不少人也利用他们从事作弊工作。如何规避这些难辨真伪的文字所产生的负面影响也成为一大难题。在3月9日智源Live第33期活动「DetectGPT:判断文本是否为机器生成的工具」中,主讲人Eric为我们讲解了DetectGPT工作背后的思路——一种基于概率曲率检测的用于检测模型生成文本的工具,它可以帮助我们更好地分辨文章的来源和可信度,对保护信息真实、防止欺诈等方面具有重要意义。本次报告主要围绕其功能,实现和效果等展开。(文末点击“阅读原文”,查看活动回放。)Ericmitchell斯坦福大学计算机系四年级博士生,由ChelseaFinn和Chri

  6. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  7. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  8. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

  9. ruby-on-rails - 将字符串转换为 ruby​​-on-rails 中的函数 - 2

    我需要一个通过输入字符串进行计算的方法,像这样function="(a/b)*100"a=25b=50function.something>>50有什么方法吗? 最佳答案 您可以使用instance_eval:function="(a/b)*100"a=25.0b=50instance_evalfunction#=>50.0请注意,使用eval本质上是不安全的,尤其是当您使用外部输入时,因为它可能包含注入(inject)的恶意代码。另请注意,a设置为25.0而不是25,因为如果它是整数a/b将导致0(整数)。

  10. ruby-on-rails - 在 Ruby on Rails 中发送响应之前如何等待多个异步操作完成? - 2

    在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.

随机推荐