阅读文件与ES6承诺

Om3*_*3ga 11 javascript node.js ecmascript-6 es6-promise

let arr = [];

function getData(fileName, type) {
    return fs.readFile(fileName,'utf8', (err, data) => {
        if (err) throw err;

        return new Promise(function(resolve, reject) {
            for (let i = 0; i < data.length; i++) {
                arr.push(data[i]);
            }

            resolve();
        });
    });
}

getData('./file.txt', 'sample').then((data) => {
    console.log(data);
});
Run Code Online (Sandbox Code Playgroud)

当我使用上面的代码并使用nodejs在命令行中运行它时,我得到以下错误.

getData('./file.txt', 'sample').then((data) => {
                               ^

TypeError: Cannot read property 'then' of undefined
Run Code Online (Sandbox Code Playgroud)

我怎么解决这个问题?

hac*_*ave 24

您需要将整个fs.readFile调用包装在new中Promise,然后根据回调结果拒绝或解析promise:

function getData(fileName, type) {
  return new Promise(function(resolve, reject){
    fs.readFile(fileName, type, (err, data) => {
        err ? reject(err) : resolve(data);
    });
  });
}
Run Code Online (Sandbox Code Playgroud)


Thé*_*ace 17

没有人告诉过util.promisify,所以我要发帖,不管这个问题多大了.你为什么要收到这条消息?

getData('./file.txt', 'sample').then((data) => {
                               ^

TypeError: Cannot read property 'then' of undefined
Run Code Online (Sandbox Code Playgroud)

getData是这里"fs.readFile"文件的包装器.fs.readfile不是一个可用的:它没有实现then函数.它建立在其他模式上,即回调模式.最着名的是Promises,这就是你想从readFile得到的东西我相信.小提醒:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

所以你可以做的就是像@hackerrdave一样自己实现它,或者我建议使用promisify:这个函数是Node.js的内置函数,它被实现为将基于回调的函数转换为基于promise的函数.你会在这里找到它:https://nodejs.org/api/util.html#util_util_promisify_original

它基本上与@hackerrdave相同,但它更强大,内置节点util.

以下是如何使用它:

const util = require('util');
const fs = require('fs');

const readFile = util.promisify(fs.readFile)
readFile("path/to/myfile").then(file => console.log(file))
Run Code Online (Sandbox Code Playgroud)

  • 我会用`const promisify = require('util').promisify;`来增强它,然后直接使用`promisify(fs.readFile)("path/to/myfile").然后(...)`.只记得正常回调的错误参数不会出现在`then`函数中,而是出现在`catch`中 (2认同)
  • 确实,我会添加catch语句,这样会更清晰。我还将编辑 require 语句,我没有考虑到这一点,但不需要 require 整个 util。 (2认同)

shm*_*mck 10

从 Node 12+ 开始,您可以使用fs.promisesAPI

请参阅下面的示例:

const { readFile } = require('fs').promises

readFile('./file.txt', { encoding: 'utf8' })
  .then((data) => console.log(data))
  .catch((error) => console.error(error));
Run Code Online (Sandbox Code Playgroud)

使用异步/等待

const { readFile } = require('fs').promises

async function readFile(filePath) {
  try {
    const data = await readFile(filePath, { encoding: 'utf8' })
    console.log(data)
  } catch (error) {
    console.error(error.message)
  }
}

readFile('./file.txt')
Run Code Online (Sandbox Code Playgroud)


Eli*_*oss 9

这是节点10.2.0的单行:

(async () => console.log(String(await require('fs').promises.readFile('./file.txt'))))();

是的,它现在开箱即用.


adr*_*727 8

const getData = (fileName, type) =>
  new Promise((resolve, reject) =>
    fs.readFile(fileName, type, (err, data) => {
      //if has error reject, otherwise resolve
      return err ? reject(err) : resolve(data);
    })
  );

getData('./file.txt', 'utf8')
  .then(data => console.log('Data: ', data))
  .catch(error => console.log('Error: ', error));
Run Code Online (Sandbox Code Playgroud)

  • @counterbeing对于没有大括号的箭头函数,`return`是隐含的. (3认同)

mik*_*ana 5

当前节点的更新从节点 10.0.0 开始,您现在可以使用fs.promises

const fs = require('fs')

(async function(){
    var fileContents = await fs.promises.readFile(FILENAME)
    var data = JSON.parse(fileContents)
})()
Run Code Online (Sandbox Code Playgroud)