Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在heavy Node.js应用程序上保持节点不返回值_Javascript_Node.js_Async Await_Node Persist - Fatal编程技术网

Javascript 在heavy Node.js应用程序上保持节点不返回值

Javascript 在heavy Node.js应用程序上保持节点不返回值,javascript,node.js,async-await,node-persist,Javascript,Node.js,Async Await,Node Persist,我有一个沉重的节点应用程序,我使用节点持久保存数据到本地数据库 在某一特定步骤中,我有以下几点: const localdb = require('node-persist') const storage = localdb.create({ttl: true}) await storage.init() function game(socket, log, opts) { // [...] async function scoreHandler(data) {

我有一个沉重的节点应用程序,我使用节点持久保存数据到本地数据库

在某一特定步骤中,我有以下几点:

const localdb = require('node-persist')
const storage = localdb.create({ttl: true})
await storage.init()

function game(socket, log, opts) {

   // [...]

    async function scoreHandler(data) {
        if (data.scoreUp) {
            await storage.setItem(data.sid,data.uid)
        } else if (data.scoreDown) {
            try {
                let uid = await storage.getItem(data.sid);

                if (typeof uid == 'undefined') {
                    return;
                }

                console.log(uid);
            } catch (e) {
                return;
            }
        }
    }
}
这段代码在长函数中有点深。一切都很简单。但有两个问题:

uid通常是未定义的。我的猜测是该文件尚未保存,因此当我尝试获取该文件上的项时,它具有未定义的值。 即使uid=='undefined',console.loguid仍然抛出许多未定义的错误。我不明白为什么,因为我回来了。 代码就是这样。这个if可能每秒调用15-20次。控制台上没有其他可能抛出未定义的代码,也没有任何写入db的代码

为什么会这样?我该怎么做才能妥善处理呢

编辑1

我明白了第二点。我忘了放打字机了

编辑2

我根据请求添加了init

如果我删除try…catch,我经常会出现以下错误:

(node:9608) UnhandledPromiseRejectionWarning: Error: [node-persist][readFile] ... does not look like a valid storage file!
    at fs.readFile (...node-persist/src/local-storage.js:277:66)
    at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:511:3)
因此,我猜测getItem正在尝试读取setItem尚未完成写入的文件。

看来node persist无法处理并发读写操作

如果在setItem进行过程中调用getItem,则会引发此错误

唯一的解决方案是由库修复,或者确保在调用setItem时从不调用getItem

我的建议是将与该存储相关的所有符号包装到自己的类中。以便以后可以轻松地用另一个库替换它

我填了一个问题:

节点persist似乎不能可靠地处理并发读写

如果在setItem进行过程中调用getItem,则会引发此错误

唯一的解决方案是由库修复,或者确保在调用setItem时从不调用getItem

我的建议是将与该存储相关的所有符号包装到自己的类中。以便以后可以轻松地用另一个库替换它

我填了一个问题:


为了补充@t.niese所说的内容,库基本上没有提供并发性。解决方案之一是序列化对库的调用。下面是对库的所有调用进行序列化的代码示例

此外,给定的库会将每个键值对写入单个文件。我认为对每个键的调用进行序列化将提供更好的吞吐量

话虽如此,这件事应该在图书馆处理

注释和取消注释节点持久化存储的选择或节点持久化周围的包装

const localdb = require('node-persist')
const when = require('when');


class QueuedStorage  {

  constructor() {
    this.storage = localdb.create({ ttl: true, logging: false})
  }

  async init() {
    await this.storage.init();
  }


  async getItem(key) {
    this.current = when(this.current,
            () => { return this.storage.getItem(key)},
            () => { return this.storage.getItem(key)});
    return this.current;
  }

  async setItem(key, value)  {
    this.current = when(this.current,
            () => { return this.storage.setItem(key,value)},
            () => { return this.storage.setItem(key,value)});
    return this.current;
  }
};


//const storage  = new QueuedStorage();
const storage = localdb.create({ ttl: true, logging: true })


async function main () {
  await storage.init()

  try {
    const key = 'DSF-AS-558-DDDF';
    const fs = new Array(10000)
      .fill(0)
      .map((e,i) => function() {
        if(i%2) return storage.getItem(key)
        else return storage.setItem(key,i)}());

    Promise.all(fs).then(values => console.log(values));

   } catch (err) {
     console.error(err)
   }
}

main().catch(err => {
  console.error(err)
})

为了补充@t.niese所说的内容,库基本上没有提供并发性。解决方案之一是序列化对库的调用。下面是对库的所有调用进行序列化的代码示例

此外,给定的库会将每个键值对写入单个文件。我认为对每个键的调用进行序列化将提供更好的吞吐量

话虽如此,这件事应该在图书馆处理

注释和取消注释节点持久化存储的选择或节点持久化周围的包装

const localdb = require('node-persist')
const when = require('when');


class QueuedStorage  {

  constructor() {
    this.storage = localdb.create({ ttl: true, logging: false})
  }

  async init() {
    await this.storage.init();
  }


  async getItem(key) {
    this.current = when(this.current,
            () => { return this.storage.getItem(key)},
            () => { return this.storage.getItem(key)});
    return this.current;
  }

  async setItem(key, value)  {
    this.current = when(this.current,
            () => { return this.storage.setItem(key,value)},
            () => { return this.storage.setItem(key,value)});
    return this.current;
  }
};


//const storage  = new QueuedStorage();
const storage = localdb.create({ ttl: true, logging: true })


async function main () {
  await storage.init()

  try {
    const key = 'DSF-AS-558-DDDF';
    const fs = new Array(10000)
      .fill(0)
      .map((e,i) => function() {
        if(i%2) return storage.getItem(key)
        else return storage.setItem(key,i)}());

    Promise.all(fs).then(values => console.log(values));

   } catch (err) {
     console.error(err)
   }
}

main().catch(err => {
  console.error(err)
})

您还可以发布节点的init调用吗?此外,如果可能,请添加更多上下文代码,因为问题可能不在这段代码中。@Biswanath I添加了一段代码和一条错误消息。我认为问题在于我试图读取一个上一个setItem尚未完成编写的文件。它包含在一个函数中显示的全部代码,包括const storage=localdb.create{ttl:true}和wait storage。init@t.niese很抱歉,我想在这里保持代码简短,并且没有包含函数声明。现在有了。那是你唯一使用存储的地方吗?您是否可以调用scoreHandler multible time,即使scoreHandler尚未完成?如果在setItem进行过程中调用getItem,则会出现错误消息。而UnhandledPromisejectionWarning表示您没有正确处理scoreHandler的结果/预期或某个callin祖先。您是否也可以发布节点的初始化调用?此外,如果可能,请添加更多上下文代码,因为问题可能不在这段代码中。@Biswanath I添加了一段代码和一条错误消息。我认为问题在于我试图读取一个上一个setItem尚未完成编写的文件。它包含在一个函数中显示的全部代码,包括const storage=localdb.create{ttl:true}和wait storage。init@t.niese很抱歉,我想在这里保持代码简短,并且没有包含函数声明。现在有了。那是你唯一使用存储的地方吗?您是否可以调用scoreHandler multible time,即使scoreHandler尚未完成?如果在setItem进行过程中调用getItem,则会出现错误消息。嗯 AndLedPromisejectionWarning表示您未正确处理scoreHandler的结果/预期或某个callin祖先。