草庐IT

node.js - Nodejs,在继续执行之前不等待 Redis 查询完成

coder 2023-11-07 原文

使用 Node.js,我需要通过从 Cassandra 获取文件路径,使用 require() 函数动态加载三个文件。我需要从每个文件中获取 Redis 中的数据,并在从 Cassandra 加载另一个文件之前进行一些验证。这里的问题是:在验证逻辑执行并提供结果之前,下一个文件开始并行加载。验证结果在加载第二个文件之后出现,这是不应该发生的。第二次文件加载应该等待第一个文件验证逻辑完成,并且只有在验证结果成功时才加载。请帮助我...如何在 node.js 中暂停或等待 Redis 完成查询???

node.js

"use strict";
var express = require('express');
var cassandra = require('cassandra-driver');
var app = express();
var Promise = require('bluebird');
var redis = Promise.promisifyAll(require('redis'));
var redisClient = redis.createClient(6379, '127.0.0.1');
var client = new cassandra.Client({contactPoints: ['127.0.0.1'], keyspace: 'poc'});
client.execute("SELECT  file FROM testqry1", function (err, result) {
    if (!err){
        if ( result.rows.length > 0 ) {
            for(var i=0; i< result.rows.length; i++){
                var filePath=result.rows[i].get('file');
                var newdat=Promise.promisifyAll(require(filePath));
                var res = newdat(redisClient);
                console.log('res:::'+res);
                if (res=='failed'){
                    return;
                }
            }
        } else {
            console.log("No results");
        }
    }
});

file1.js

var crypto = require('crypto');
var redisValue='';
module.exports = function(redisclient){

redisclient.hmgetAsync("testdata", "text1").then(function(redisValue){
      console.log('value from redis::'+redisValue) 
  }).then(function(){
    var hashedUserID = crypto.createHmac('sha256', 'sample')
                   .update('helloworld')
                   .digest('hex'); 

    function disp(value) {
        console.log('value::'+value);
      }
      disp(hashedUserID);

      console.log('redisValue::'+redisValue);
      if(hashedUserID =='e043e7e68058c8a4cd686db38f01771bd7a04b8bb9a658d3cb40d0be45935094'){
        redata='true';
      }else{
        redata='false';
      }

      console.log('redata::'+redata)
})
}

file2.js & file3.js 内容相同

var result1='';
module.exports = function(redisclient){
    redisclient.hmget("testdata", "text1" , function(err, redisValue){  
      console.log('redisValue2 == %s',redisValue);
      if(redisValue == 'test value'){
        result1 = "success";
      }else{
        result1="failed";
      }
    });

    return result1;
} 

输出:

res:::undefined
res:::
res:::
value from redis::test data here
value::e043e7e68058c8a4cd686db38f01771bd7a04b8bb9a658d3cb40d0be45935094
redisValue::
redata::true
redisValue2 == test data here
redisValue3 == hello world test data

最佳答案

你说 file2/3 是“相同的内容”,但它们不在一个关键区域。根据 Bluebird 的 promisifyAll 文档(参见 http://bluebirdjs.com/docs/api/promise.promisifyall.html ),此功能为 Redis 客户端中的每个核心功能创建了一个 ...Async 版本。您在第一种情况下调用了 hmgetAsync,但在其他情况下您只调用了 hmget

这很重要,因为您使用的是异步模式但具有非异步代码结构。在 file2/3 中,您在异步回调中设置了 result1,然后在调用可能返回之前在每次调用下方返回它。

你有两个选择:

1:除了redis客户端之外,你还可以通过传入回调将file2/3/etc转换为完全传统的模式:

module.exports = function(redisclient, callback){

而不是返回 result1,然后您将使用此值调用回调:

if(redisValue == 'test value'){
    callback(null, "success");
} else {
    callback("failed", null);
}

2:您可以将 file2/3/..N 转换为基于 Promise 的,在这种情况下您不需要 promisifyAll(require(...)) 它们 - 您可以简单地require() 它们。这样的模式可能看起来像:

module.exports = function(redisclient){
    return redisclient.hmgetAsync("testdata", "text1");
};

这是一个更简单、更清晰的选项,如果你继续使用它,你会发现你甚至可以消除 require() 并简单地在 file1 中执行 hmgetAsync 并返回适当的数据 Cassandra 。但如果不了解您的具体应用需求,就很难知道。无论如何,基于 Promise 的模式通常更短更简洁,但并不总是更好——使用它们会产生适度的性能开销。走哪条路由您决定 - 两者都行。

关于node.js - Nodejs,在继续执行之前不等待 Redis 查询完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37053484/

有关node.js - Nodejs,在继续执行之前不等待 Redis 查询完成的更多相关文章

  1. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  2. ruby - Chef 执行非顺序配方 - 2

    我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul

  3. ruby - 如何在 Rails 4 中使用表单对象之前的验证回调? - 2

    我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser

  4. ruby - 即使失败也继续进行多主机测试 - 2

    我已经构建了一些serverspec代码来在多个主机上运行一组测试。问题是当任何测试失败时,测试会在当前主机停止。即使测试失败,我也希望它继续在所有主机上运行。Rakefile:namespace:specdotask:all=>hosts.map{|h|'spec:'+h.split('.')[0]}hosts.eachdo|host|begindesc"Runserverspecto#{host}"RSpec::Core::RakeTask.new(host)do|t|ENV['TARGET_HOST']=hostt.pattern="spec/cfengine3/*_spec.r

  5. ruby - 为什么 Ruby 的 each 迭代器先执行? - 2

    我在用Ruby执行简单任务时遇到了一件奇怪的事情。我只想用每个方法迭代字母表,但迭代在执行中先进行:alfawit=("a".."z")puts"That'sanalphabet:\n\n#{alfawit.each{|litera|putslitera}}"这段代码的结果是:(缩写)abc⋮xyzThat'sanalphabet:a..z知道为什么它会这样工作或者我做错了什么吗?提前致谢。 最佳答案 因为您的each调用被插入到在固定字符串之前执行的字符串文字中。此外,each返回一个Enumerable,实际上您甚至打印它。试试

  6. ruby - 继续,未定义 callcc 方法 - 2

    我想学习一些关于Continuation的知识,使用callcc方法从一些文章中键入几个示例,但我遇到了错误:NoMethodError:undefinedmethod`callcc'formain:Objectfrom(pry):2:in`'没有文章提到包含延续库。那么如何解决这个问题呢?谢谢编辑:ruby1.9.2p290(2011-07-09修订版32553)[x86_64-linux] 最佳答案 您需要要求“继续”。require'continuation' 关于ruby-继续,

  7. ruby - 检查是否通过 require 执行或导入了 Ruby 程序 - 2

    如何检查Ruby文件是否是通过“require”或“load”导入的,而不是简单地从命令行执行的?例如:foo.rb的内容:puts"Hello"bar.rb的内容require'foo'输出:$./foo.rbHello$./bar.rbHello基本上,我想调用bar.rb以不执行puts调用。 最佳答案 将foo.rb改为:if__FILE__==$0puts"Hello"end检查__FILE__-当前ruby​​文件的名称-与$0-正在运行的脚本的名称。 关于ruby-检查是否

  8. ruby - 安装libv8(3.11.8.13)出错,Bundler无法继续 - 2

    运行bundleinstall后出现此错误:Gem::Package::FormatError:nometadatafoundin/Users/jeanosorio/.rvm/gems/ruby-1.9.3-p286/cache/libv8-3.11.8.13-x86_64-darwin-12.gemAnerroroccurredwhileinstallinglibv8(3.11.8.13),andBundlercannotcontinue.Makesurethat`geminstalllibv8-v'3.11.8.13'`succeedsbeforebundling.我试试gemin

  9. postman——集合——执行集合——测试脚本——pm对象简单示例02 - 2

    //1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json

  10. ruby-on-rails - rbenv:从 RVM 移动到 rbenv 后,在 Jenkins 执行 shell 中找不到命令 - 2

    我从Ubuntu服务器上的RVM转移到rbenv。当我使用RVM时,使用bundle没有问题。转移到rbenv后,我在Jenkins的执行shell中收到“找不到命令”错误。我内爆并删除了RVM,并从~/.bashrc'中删除了所有与RVM相关的行。使用后我仍然收到此错误:rvmimploderm~/.rvm-rfrm~/.rvmrcgeminstallbundlerecho'exportPATH="$HOME/.rbenv/bin:$PATH"'>>~/.bashrcecho'eval"$(rbenvinit-)"'>>~/.bashrc.~/.bashrcrbenvversions

随机推荐