简体   繁体   English

将 `fs.readdir` 与 `.then` 链接起来以返回一个数组

[英]chaining `fs.readdir` with a `.then` to return an array

I am trying to create an array of specific files in a directory;我正在尝试在目录中创建一组特定文件; which will go through a few test cases to make sure it fits a given criteria.这将通过一些测试用例来确保它符合给定的标准。

I'm using the fs.readdir method, but it doesn't return a promise meaning I cannot push to an array .我正在使用fs.readdir方法,但它没有返回promise这意味着我无法push送到array

My idea was to populate an array ( arr ) with the files I actually want to output and then do something with that array.我的想法是用我真正想要输出的文件填充一个数组( arr ),然后对该数组做一些事情。 But because readdir is asynchronous and I can't chain a .then() onto it, my plans are quashed.但是因为readdir是异步的并且我不能将.then()到它上面,所以我的计划被取消了。

I've also tried the same thing with readdirSync to no avail.我也用readdirSync尝试了同样的事情,但无济于事。

const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));

var arr = [];

fs.readdirAsync(folder).then( files => {
  files.forEach(file => {
    fs.stat(folder + '/' + file, (err, stats) => {
       if(!stats.isDirectory()) {
         arr.push(file);
        return;
      }
     });
   });
})
.then( () => {
  console.log(arr);
});

fs.readdir is callback based, so you can either promisify it using bluebird or Node.js util package (or writing a simple implementation of it yourself), or simply wrap the call in a promise, like so: fs.readdir是基于回调,这样你就可以promisify它使用蓝鸟或Node.js的util包(或写一个简单的实现自己的话),或者干脆换了电话的承诺,就像这样:

// Wrapped in a promise
new Promise((resolve, reject) => {
    return fs.readdir('/folderpath', (err, filenames) => err != null ? reject(err) : resolve(filenames))
})

Or the custom promisify function:或者自定义promisify函数:

// Custom promisify
function promisify(fn) {
  /**
   * @param {...Any} params The params to pass into *fn*
   * @return {Promise<Any|Any[]>}
   */
  return function promisified(...params) {
    return new Promise((resolve, reject) => fn(...params.concat([(err, ...args) => err ? reject(err) : resolve( args.length < 2 ? args[0] : args )])))
  }
}

const readdirAsync = promisify(fs.readdir)
readdirAsync('./folderpath').then(filenames => console.log(filenames))

Just plain javascript, no libs:只是普通的javascript,没有库:

 function foo (folder, enconding) { return new Promise(function(resolve, reject) { fs.readdir(folder,enconding, function(err, filenames){ if (err) reject(err); else resolve(filenames); }); }); };

eg例如

 foo(someFolder, "someEncoding") .then((files) => console.log(files)) .catch((error) => console.log(error));

I figured it out;我想到了; I just needed to use statSync instead of stat我只需要使用statSync而不是stat

const fs = require('fs');

var arr = [];

var files = fs.readdirSync(folder);

files.forEach(file => {
  let fileStat = fs.statSync(folder + '/' + file).isDirectory();
  if(!fileStat) {
    arr.push(file);
  }
});

console.log(arr);

You can now use ES6 destructuring assignment ( documentation ) :您现在可以使用ES6 解构赋值文档):

const
    fs = require('fs'),
    FILES = [...fs.readdirSync('src/myfolder')];

console.log(FILES);

if you want to use a promise instead of a callback you can promisify fs .如果你想使用承诺而不是回调,你可以承诺fs

const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));

fs.readdirAsync('./some').then()

http://bluebirdjs.com/docs/api/promise.promisifyall.html http://bluebirdjs.com/docs/api/promise.promisifyall.html

您是否尝试过fs-extra模块?

new Promise((resolve, reject) => {
    return fs.readdir('/folderpath', (err, filenames) => err ? reject(err) : resolve(filenames))
})

Do not err !== undefined because err is actually null !!不要err !== undefined因为 err 实际上是null !!

As of Node.js v10, there is an fs.promises API that supports this:从 Node.js v10 开始,有一个fs.promises API 支持:

const fs = require('fs');

var arr = [];

fs.promises.readdir(folder).then( files => {
  files.forEach(file => {
    fs.stat(folder + '/' + file, (err, stats) => {
       if(!stats.isDirectory()) {
         arr.push(file);
        return;
      }
     });
   });
})
.then( () => {
  console.log(arr);
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM