在node.js中使初始化异步 [英] Make Initialization Asynchronous in node.js

查看:103
本文介绍了在node.js中使初始化异步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在node.js程序中初始化键类,但是指令以任意顺序运行,因此初始化错误.我已经尝试过使初始化发生在定义和单独的函数中.都行不通.有什么我想念的吗?

I am trying to initialize a key class in a node.js program, but the instructions are running in arbitrary order and therefore it is initializing wrong. I've tried both making initialization happen in the definition and in a separate function; neither works. Is there something that I'm missing?

当前代码:

class BotState {
    constructor() {
        this.bios = {}
        this.aliases = {};
        this.stories = {};
        this.nextchar = 0;
    }
}

var ProgramState = new BotState();

BotState.prototype.Initialize = function() {
    this.bios = {};
    var aliases = {};
    var nextchar = 0;
    this.nextchar = 0;
    fs.readdir(biosdir, function (err, files) {
        if (err) throw err;
        for (var file in files) {
            fs.readFile(biosdir + file + ".json", {flag: 'r'}, (err, data) => {
                if (err) throw err;
                var bio = JSON.parse(data);
                var index = bio["charid"];
                this.bios[index] = bio;
                for (var alias in bio["aliaslist"]) {
                    this.aliases[bio["aliaslist"][alias].toLowerCase()] = index;
                }
                if (index >= nextchar) {
                    nextchar = index + 1;
                }
            })
        }
        this.stories = {};
        this.nextchar = Math.max(Object.keys(aliases).map(key => aliases[key]))+1;
    });
}

ProgramState.Initialize();

是否有一些通用的方法可以使node.js只是...按命令的顺序运行命令,而不是任意命令?

Is there some general way to make node.js just... run commands in the order they're written, as opposed to some arbitrary one?

(抱歉,如果代码草率;我更关心的是使代码执行正确的事情而不是使代码看起来不错.)

(Apologies if the code is sloppy; I was more concerned with making it do the right thing than making it look nice.)

推荐答案

您正在循环中运行异步操作,这会导致循环继续运行,并且异步操作以某种随机顺序完成,因此您将以某种随机顺序进行处理.控制循环的最简单方法是切换到 fs 库的基于承诺的版本,然后使用 async/await 导致 for 循环暂停并等待异步操作完成.您可以这样做:

You are running an asynchronous operation in a loop which causes the loop to continue running and the asynchronous operations finish in some random order so you process them in some random order. The simplest way to control your loop is to switch to the promise-based version of the fs library and then use async/await to cause your for loop to pause and wait for the asynchronous operation to complete. You can do that like this:

const fsp = require('fs').promises;

class BotState {
    constructor() {
        this.bios = {}
        this.aliases = {};
        this.stories = {};
        this.nextchar = 0;
    }
}

var ProgramState = new BotState();

BotState.prototype.Initialize = async function() {
    this.bios = {};
    this.nextchar = 0;

    let aliases = {};
    let nextchar = 0;
    const files = await fsp.readdir(biosdir);

    for (const file of files) {
        const data = await fsp.readFile(biosdir + file + ".json", {flag: 'r'});
        const bio = JSON.parse(data);
        const index = bio.charid;
        const list = bio.aliaslist;
        this.bios[index] = bio;
        for (const alias of list) {
            this.aliases[alias.toLowerCase()] = index;
        }
        if (index >= nextchar) {
            nextchar = index + 1;
        }
    }

    this.stories = {};
    // there is something wrong with this line of code because you NEVER
    // put any  data in the variable aliases
    this.nextchar = Math.max(Object.keys(aliases).map(key => aliases[key]))+1;
}

ProgramState.Initialize();

请注意,使用 aliases 局部变量存在一个问题,因为您从未在该数据结构中放入任何内容,而是试图在函数的最后一行中使用它.我不知道您要在此完成什么,所以您将必须解决该问题.

Note, there's a problem with your usage of the aliases local variable because you never put anything in that data structure, yet you're trying to use it in the last line of the function. I don't know what you're trying to accomplish there so you will have to fix that.

此外,请注意,您永远不应使用 for/in 来迭代数组.这会迭代对象的属性,该对象的属性可能不仅包括数组元素. for/of 专门用于像数组一样迭代一个可迭代对象,它还可以在获取每个值而不是每个索引时保存数组取消引用.

Also, note that you should never use for/in to iterate an array. That iterates properties of an object which can include more than just the array elements. for/of is made precisely for iterating an iterable like an array and it also saves the array dereference too as it gets you each value, not each index.

这篇关于在node.js中使初始化异步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆