Promise不适用于node-dir读取文件

时间:2019-11-24 14:22:45

标签: javascript node.js es6-promise

我尝试使用Nodejs中的node-dir模块从目录中读取文件,在读取所有文件之后,我将它们发送到Redis,最后关闭Redis连接,因此我使用了Promise。但是,到Redis的退出连接总是要首先执行,“ then”子句似乎不会等到Promise解决后,导致连接在任何持久性发生之前都被关闭,我可以寻求您的帮助吗?

new Promise((resolved, failed) => {
    nodeDir.readFiles(dirName, options, (err, file, nextCallback) => {
        if(err){throw err};
        //...logics to get key&value
        redisClient.set(key, value);
        nextCallback();
    });
    resolved(); //it finally resolves
    }).then(()=>{
    redisClient.quit(); //this line never waits, it always executes first
})

3 个答案:

答案 0 :(得分:0)

让我们看一下与您相似的代码块,以了解这里出了什么问题:

new Promise((resolved, failed) => {
   setTimeout(function(){}, 3000);
      resolved(); 
   }).then(()=>{
   console.log("DONE");
})

在这种情况下,立即在控制台中打印文本“ DONE”。

但是,如果我们像下面这样写,我们会得到一些不同的东西:

new Promise((resolved, failed) => {
   setTimeout(function(){
      resolved();
   }, 3000);  
   }).then(()=>{
   console.log("DONE");
})

在这种情况下,“ DONE”将在3秒钟后打印到控制台。您立即兑现了诺言,这就是问题所在。只要解决所有副作用,就可以尝试解决。希望能帮助到你。

答案 1 :(得分:0)

我检查了node-dir模块的API,它实际上提供了readFiles的形式,该形式提供了在处理完所有文件后执行的回调,然后我修改了代码以在其中进行解析,最终按预期工作,非常感谢@Plabon Dutta!

修改后的版本

new Promise((resolved, failed) => {
  nodeDir.readFiles(dirName, (err, file, nextCallback) => {
    // file handling
  }, (err, files) => {
    resolved(); //here does the resolve
  });
}).then(()=>{
  redisClient.quit();
})

答案 2 :(得分:0)

这是来自node-dir库的readFiles的通用,应许返回版本。注意,它的唯一工作是返回一个承诺,当完成回调被调用时,该承诺将得到解决。请注意,它不包含then块。

// a promise returning form of node-dir readFiles
// pass a file handling callback, but no completion function
function readFilesQ(dirname, options, fileCallback) {
  return new Promise((resolved, failed) => {
    // this invocation passes a completion function that resolves the promise
    nodeDir.readFiles(dirname, options, fileCallback, (err, files) => {
      err ? failed(err) : resolved(files)
    });
  })
}

现在,您可以从外部提供文件处理和完成逻辑,具体取决于您需要读取文件的位置。

readFilesQ(someDirname, someOptions, (err, content, next) => {
  // handle content for each file, call next
}).then(files => {
  // handle correct completion
}).catch(err => {
  // handle error
})