首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法使用NodeJS TypeScript代码从Redis读取数据

无法使用NodeJS TypeScript代码从Redis读取数据
EN

Stack Overflow用户
提问于 2020-06-11 12:29:12
回答 2查看 7.2K关注 0票数 0

我通过从客户端传递过滤器对象(也就是我的hashkey )来调用名为loadFilteredPolicy()的方法,但是它的方法get()或hgetall()永远不会被执行,如果没有从Redis服务器获取数据而不引发任何错误,控制就会停止。让我确认一下,我可以调试,并且可以确保this.redisInstance上有redis对象,但不确定为什么方法不执行。我可以通过命令hgetall直接使用redis-cli获取相同的数据。

我还要告诉您的另一件事是,当我在上面取消注释承诺行(等待this.redisInstance.hgetall)并再次调试时,this.redisInstance返回未定义的内容。我不知道发生了什么。我以前使用过JS,但是TypeScript不多,从早上开始我就陷入了这个错误,现在已经是晚上了。

这是我的TypeScript代码(adapter.ts),它被编译成JS文件:-

代码语言:javascript
复制
import { Helper, Model, FilteredAdapter } from 'casbin';
import * as redis from 'redis';

interface IConnectionOptions {
    host: string;
    port: number;
}
class Line {
    ptype: string;
    v0: string;
    v1: string;
    v2: string;
    v3: string;
    v4: string;
    v5: string;
}
export class RedisAdapter implements FilteredAdapter {

    private redisInstance = null;
    private policies = null;
    private filtered = false;

    public isFiltered(): boolean {
        return this.filtered;
    }

    private deliveredOptions = {
        retry_strategy(options) {
            if (options.error && options.error.code === 'ECONNREFUSED') {
                return new Error('The server refused the connection');
            }
            if (options.total_retry_time > 1000 * 60 * 60) {
                return new Error('Retry time exhausted');
            }
            if (options.attempt > 10) {
                return undefined;
            }
            // reconnect after
            return Math.min(options.attempt * 100, 300);
        },
    };

    /**
     * Helper Methods
     */

    savePolicyLine(ptype, rule) {
        const line = new Line();
        line.ptype = ptype;
        if (rule.length > 0) {
            line.v0 = rule[0];
        }

        if (rule.length > 1) {
            line.v1 = rule[1];
        }

        if (rule.length > 2) {
            line.v2 = rule[2];
        }

        if (rule.length > 3) {
            line.v3 = rule[3];
        }

        if (rule.length > 4) {
            line.v4 = rule[4];
        }

        if (rule.length > 5) {
            line.v5 = rule[5];
        }
        return line;
    }
    loadPolicyLine(line, model) {
        console.log("load Policies line called");
        let lineText = line.ptype;
        if (line.v0) {
            lineText += ", " + line.v0;
        }
        if (line.v1) {
            lineText += ", " + line.v1;
        }
        if (line.v2) {
            lineText += ", " + line.v2;
        }
        if (line.v3) {
            lineText += ", " + line.v3;
        }
        if (line.v4) {
            lineText += ", " + line.v4;
        }
        if (line.v5) {
            lineText += ", " + line.v5;
        }
        Helper.loadPolicyLine(lineText, model);
    }

    storePolicies(policies) {
        return new Promise((resolve, reject) => {
            console.log({ r: this.redisInstance });
            this.redisInstance.del('policies');
            this.redisInstance.set('policies', JSON.stringify(policies), (err, reply) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(reply);
                }
            });
        });
    }

    reducePolicies(policies, ptype, rule) {
        let i = rule.length;
        let policyIndex = policies.fieldIndex((policy) => {
            let flag = false;
            flag = policy.ptype === ptype ? true : false;
            flag = i > 5 && policy.v5 === rule[5] ? true : false;
            flag = i > 4 && policy.v4 === rule[4] ? true : false;
            flag = i > 3 && policy.v3 === rule[3] ? true : false;
            flag = i > 2 && policy.v2 === rule[2] ? true : false;
            flag = i > 1 && policy.v0 === rule[1] ? true : false;
            return flag;
        });
        if (policyIndex !== -1) {
            return policies.splice(policyIndex, 1);
        }
        return [];
    }

    constructor(options: IConnectionOptions) {
        this.redisInstance = redis.createClient(
            {
                ...options,
                ...this.deliveredOptions,
            },
        );
    }

    static async newAdapter(options: IConnectionOptions) {
        const adapter = new RedisAdapter(options);
        await new Promise(resolve => adapter.redisInstance.on('connect', resolve));
        return adapter;
    }

    /**
     * Adapter Methods
     */
    public async loadPolicy(model) {
        this.redisInstance.get("policies", (err, policies) => {
            var AdapterRef = this;
            console.log("Loading Policies...\n", policies);
            if (!err) {
                policies = JSON.parse(policies);
                this.policies = policies;//For add and remove policies methods
                console.log(policies);
                policies.forEach(function (policy, index) {
                    AdapterRef.loadPolicyLine(policy, model);
                });
                console.log("Policies are loaded");
            } else {
                return err;
            }
        });
    }

    public async loadFilteredPolicy(model: Model, filter: object): Promise<void> {
        let key = filter['hashKey'];
        //return await new Promise(function (resolve, reject) {
            this.redisInstance.hgetall(key, (err, policies) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(err);
                    var AdapterRef = this;
                    console.log("Loading filtered Policies...\n", policies);
                    policies = JSON.parse(policies);
                    this.policies = policies;//For add and remove policies methods
                    console.log(policies);
                    policies.forEach(function (policy, index) {
                        AdapterRef.loadPolicyLine(policy, model);
                    });
                    console.log("Filtered Policies are loaded...");
                    this.filtered = true;
                }
            });
        //})
    }

    public async savePolicy(model: Model): Promise<boolean> {
        const policyRuleAST = model.model.get("p");
        const groupingPolicyAST = model.model.get("g");
        let policies = [];

        //var rows2 = <Array<any>>policyRuleAST;
        //var rows2 = <Array<any>>groupingPolicyAST;

        for (const [ptype, ast] of Object.entries(policyRuleAST)) {
            for (const rule of ast.policy) {
                const line = this.savePolicyLine(ptype, rule);
                policies.push(line);
            }
        }

        for (const [ptype, ast] of Object.entries(groupingPolicyAST)) {
            for (const rule of ast.policy) {
                const line = this.savePolicyLine(ptype, rule);
                policies.push(line);
            }
        }
        //this.storePolicies(policies);

        return new Promise((resolve, reject) => {
            console.log({ r: this.redisInstance });
            this.redisInstance.del('policies');
            this.redisInstance.set('policies', JSON.stringify(policies), (err, reply) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(true);
                }
            });
        });
    }

    async addPolicy(sec, ptype, rule) {
        const line = this.savePolicyLine(ptype, rule);
        this.policies.push(line);
        this.storePolicies(this.policies);
        //reSave the policies
    }

    async removePolicy(sec, ptype, rule) {
        let result = this.reducePolicies(this.policies, ptype, rule);
        //the modified policies
        if (result.length) { //if length>0
            this.policies = result;
            //Store in Redis
            this.storePolicies(this.policies);
        } else {
            // console.IN("No Policy found");
            throw new Error("No Policy Found");
        }
    }

    public async removeFilteredPolicy(sec: string, ptype: string, fieldIndex: number, ...fieldValues: string[]) {
        throw new Error("Method not implemented");
    }
}

对应的adapter.js :-

代码语言:javascript
复制
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RedisAdapter = void 0;
const casbin_1 = require("casbin");
const redis = require("redis");
class Line {
}
class RedisAdapter {
    constructor(options) {
        this.redisInstance = null;
        this.policies = null;
        this.filtered = false;
        this.deliveredOptions = {
            retry_strategy(options) {
                if (options.error && options.error.code === 'ECONNREFUSED') {
                    return new Error('The server refused the connection');
                }
                if (options.total_retry_time > 1000 * 60 * 60) {
                    return new Error('Retry time exhausted');
                }
                if (options.attempt > 10) {
                    return undefined;
                }
                return Math.min(options.attempt * 100, 300);
            },
        };
        this.redisInstance = redis.createClient(Object.assign(Object.assign({}, options), this.deliveredOptions));
    }
    isFiltered() {
        return this.filtered;
    }
    savePolicyLine(ptype, rule) {
        const line = new Line();
        line.ptype = ptype;
        if (rule.length > 0) {
            line.v0 = rule[0];
        }
        if (rule.length > 1) {
            line.v1 = rule[1];
        }
        if (rule.length > 2) {
            line.v2 = rule[2];
        }
        if (rule.length > 3) {
            line.v3 = rule[3];
        }
        if (rule.length > 4) {
            line.v4 = rule[4];
        }
        if (rule.length > 5) {
            line.v5 = rule[5];
        }
        return line;
    }
    loadPolicyLine(line, model) {
        console.log("load Policies line called");
        let lineText = line.ptype;
        if (line.v0) {
            lineText += ", " + line.v0;
        }
        if (line.v1) {
            lineText += ", " + line.v1;
        }
        if (line.v2) {
            lineText += ", " + line.v2;
        }
        if (line.v3) {
            lineText += ", " + line.v3;
        }
        if (line.v4) {
            lineText += ", " + line.v4;
        }
        if (line.v5) {
            lineText += ", " + line.v5;
        }
        casbin_1.Helper.loadPolicyLine(lineText, model);
    }
    storePolicies(policies) {
        return new Promise((resolve, reject) => {
            console.log({ r: this.redisInstance });
            this.redisInstance.del('policies');
            this.redisInstance.set('policies', JSON.stringify(policies), (err, reply) => {
                if (err) {
                    reject(err);
                }
                else {
                    resolve(reply);
                }
            });
        });
    }
    reducePolicies(policies, ptype, rule) {
        let i = rule.length;
        let policyIndex = policies.fieldIndex((policy) => {
            let flag = false;
            flag = policy.ptype === ptype ? true : false;
            flag = i > 5 && policy.v5 === rule[5] ? true : false;
            flag = i > 4 && policy.v4 === rule[4] ? true : false;
            flag = i > 3 && policy.v3 === rule[3] ? true : false;
            flag = i > 2 && policy.v2 === rule[2] ? true : false;
            flag = i > 1 && policy.v0 === rule[1] ? true : false;
            return flag;
        });
        if (policyIndex !== -1) {
            return policies.splice(policyIndex, 1);
        }
        return [];
    }
    static async newAdapter(options) {
        const adapter = new RedisAdapter(options);
        await new Promise(resolve => adapter.redisInstance.on('connect', resolve));
        return adapter;
    }
    async loadPolicy(model) {
        this.redisInstance.get("policies", (err, policies) => {
            var AdapterRef = this;
            console.log("Loading Policies...\n", policies);
            if (!err) {
                policies = JSON.parse(policies);
                this.policies = policies;
                console.log(policies);
                policies.forEach(function (policy, index) {
                    AdapterRef.loadPolicyLine(policy, model);
                });
                console.log("Policies are loaded");
            }
            else {
                return err;
            }
        });
    }
    async loadFilteredPolicy(model, filter) {
        let key = filter['hashKey'];
        //await new Promise(function (resolve, reject) {

            await this.redisInstance.hgetall(key, (err, policies) => {
                if (err) {
                    return err;
                }
                else {
                    var AdapterRef = this;
                    console.log("Loading filtered Policies...\n", policies);
                    policies = JSON.parse(policies);
                    this.policies = policies;
                    console.log(policies);
                    policies.forEach(function (policy, index) {
                        AdapterRef.loadPolicyLine(policy, model);
                    });
                    console.log("Filtered Policies are loaded...");
                    this.filtered = true;
                }
            });
       // });
    }
    async savePolicy(model) {
        const policyRuleAST = model.model.get("p");
        const groupingPolicyAST = model.model.get("g");
        let policies = [];
        for (const [ptype, ast] of Object.entries(policyRuleAST)) {
            for (const rule of ast.policy) {
                const line = this.savePolicyLine(ptype, rule);
                policies.push(line);
            }
        }
        for (const [ptype, ast] of Object.entries(groupingPolicyAST)) {
            for (const rule of ast.policy) {
                const line = this.savePolicyLine(ptype, rule);
                policies.push(line);
            }
        }
        return new Promise((resolve, reject) => {
            console.log({ r: this.redisInstance });
            this.redisInstance.del('policies');
            this.redisInstance.set('policies', JSON.stringify(policies), (err, reply) => {
                if (err) {
                    reject(err);
                }
                else {
                    resolve(true);
                }
            });
        });
    }
    async addPolicy(sec, ptype, rule) {
        const line = this.savePolicyLine(ptype, rule);
        this.policies.push(line);
        this.storePolicies(this.policies);
    }
    async removePolicy(sec, ptype, rule) {
        let result = this.reducePolicies(this.policies, ptype, rule);
        if (result.length) {
            this.policies = result;
            this.storePolicies(this.policies);
        }
        else {
            throw new Error("No Policy Found");
        }
    }
    async removeFilteredPolicy(sec, ptype, fieldIndex, ...fieldValues) {
        throw new Error("Method not implemented");
    }
}
exports.RedisAdapter = RedisAdapter;

如果你能建议我让这段代码工作,我会非常感激的。此适配器源代码的GitHub链接可在这里获得,https://github.com/vinod827/node-casbin-redis-adapter.git

谢谢,

更新代码,未工作的

代码语言:javascript
复制
async loadFilteredPolicy(model, filter) {
    let key = filter['hashKey'];
    let filteredPolicies = await this.getFilteredPolicies(key).then(data => { return data });
    console.log(filteredPolicies);
}
getFilteredPolicies = async (hashKey) => {
    return await new Promise(function (resolve, reject) {
        this.redisInstance.hgetall((hashKey), function (err, data) {
            if (err) {
                reject(err);
            } else {
                resolve(data);
            }
        })
    })
};
EN

回答 2

Stack Overflow用户

发布于 2020-06-13 02:35:39

我认为您需要重新学习Promise的使用,至少您需要知道何时使用resolve()

请参阅:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

顺便说一句,不要用typescript作为借口,这里只有javascript

我来这里是为了给你们提供一个最低限度的实现,可以:

代码语言:javascript
复制
import * as redis from "redis";

const client = redis.createClient(6379, "127.0.0.1");

function func() {
  return new Promise((resolve, reject) => {
    client.hgetall("myhash", (err, data) => {
      if (err) {
        reject(err);
      }
      resolve(data);
    });
  });
}

async function main() {
  const data = await func();
  console.log(data);
}

main();
票数 0
EN

Stack Overflow用户

发布于 2020-06-15 12:46:53

你能在https://github.com/vinod827/node-casbin-redis-adapter/blob/master/src/adapter.ts#L150上试试下面的代码吗?

代码语言:javascript
复制
public async loadPolicy(model) {
    return new Promise((resolve, reason)=> {
        this.redisInstance.get("policies", (err, policies) => {
            console.log("Loading Policies...\n", policies);
            if (!err) {
                policies = JSON.parse(policies);
                console.log(policies);
                policies.forEach((policy, index)=> {
                    this.loadPolicyLine(policy, model);
                });
                console.log("Policies are loaded");
                resolve()
            } else {
                reason(err)
            }
        });
    })
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62324434

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档