打字稿:无法将 json 文件内容加载到数组中

Typescript: cannot load json file contents into array

我需要从具有文件结构的 json 文件 (api.json) 加载我的 apikeys api.json:

{
"service1": ["apikey1", "apikey2"],
"service2": ["apikey1", "apikey2"],
}

我有一个描述键和值的 class:

class ApiKey {
   constructor(apiName: String, apiKeys: Array<String>)
}

我有一个 class,它将所有键从文件加载到数组:

//read file async: 
    import { readFile } from 'fs'
    import { promisify } from 'util'
    import { join } from 'path'

    export class ApikeysService {

    constructor(private apiKeys: Array<ApiKey> = new Array<ApiKey>()) {
        this.loadKeys()
    }

    public loadKeys () {
        const filePath      = join(__dirname, "../../../", "api.json");
        const readfile      = promisify(readFile);
        const result        = readfile(filePath, "utf8")
                                .then(content => JSON.parse(content))
                                .then(result => {
                                    Object.keys(result).forEach(key => {
                                        this.apikeys.push(new ApiKey(key, result[key]))
                                    })
                                })
        
    }

    public getKeyFor(name: String) {
        return this.keyCounters.find(x => x.keyname == name).apiKeys
    }

}

我的测试:

describe('should load api keys', () => { 
    it("should load apikeys from file", async () => {
         const service = new ApikeysService ()
         it("should load api keys for service1", () => {
    

         expect(service.getKeyFor("service1")[0]).toEqual("apikey1")
         expect(service.getKeyFor("service1")[1]).toEqual("apikey2")

    })
})

测试结果:

expect(received).toEqual(expected) // deep equality

>     Expected: "apikey1"
>     Received: undefined

我尝试了很多不同的方法来将内容从文件加载到 class 中的数组(也异步)但是它不起作用

您在构造函数中触发异步函数,然后直接检查结果 - 您没有机会解析 promise。它不是同步的。

要么 return result 来自 loadKeys 并确保等待它,要么使用 readFileSync.

将其更改为同步

示例 1

export class ApikeysService {
    constructor(private apiKeys: Array<ApiKey> = new Array<ApiKey>()) {
        this.loadKeys()
    }

    public loadKeys () {
        const filePath      = join(__dirname, "../../../", "api.json");
        const readfile      = promisify(readFile);
        const content       = JSON.parse(readFileSync(filePath, "utf8"));

        Object.keys(result).forEach(key => {
            this.apikeys.push(new ApiKey(key, result[key]))
        })        
    }

    public getKeyFor(name: String) {
        return this.keyCounters.find(x => x.keyname == name).apiKeys
    }
}

示例 2

export class ApikeysService {
    constructor(private apiKeys: Array<ApiKey> = new Array<ApiKey>()) {
        // this.loadKeys()
    }

    public loadKeys () {
        const filePath      = join(__dirname, "../../../", "api.json");
        const readfile      = promisify(readFile);
        const result        = readfile(filePath, "utf8")
                                .then(content => JSON.parse(content))
                                .then(result => {
                                    Object.keys(result).forEach(key => {
                                        this.apikeys.push(new ApiKey(key, result[key]))
                                    })
                                })
        return result;   
    }

    public getKeyFor(name: String) {
        return this.keyCounters.find(x => x.keyname == name).apiKeys
    }
}

describe('should load api keys', () => { 
    it("should load apikeys from file", async () => {
        const service = new ApikeysService ()
        await service.loadKeys();

        it("should load api keys for service1", () => {
            expect(service.getKeyFor("service1")[0]).toEqual("apikey1")
            expect(service.getKeyFor("service1")[1]).toEqual("apikey2")
        })
    })
})