nodejs收到错误TypeError:无法读取未定义的属性“ then”

时间:2020-05-21 13:38:56

标签: node.js

我的功能是

generateReport: function() {
          const copyFolder = (src, dest) => {
            return new Promise((res, rej) => {
                fsext.copySync(src, dest, (err, data) => {
                if (err) {
                  return rej(err);
                }
                return res(data);
              });
            });
          };

        const readFile = src => {
            return new Promise((res, rej) => {
                fs.readFile(src, (err, data) => {
                if (err) {
                    return rej(err);
                }
                return res(data);
                });
            });
        };

        copyFolder("./sample/", "./login/sample/" )
        .then(data => {
            return readFile("./sample/Duration_Suite.json", "utf8");
        })
        .then(data => {
        jsonData += data;
        console.log(jsonData)
        })  
    }

运行此功能时,出现错误

TypeError:无法读取未定义的属性“ then”

请让我知道我在哪里做错

2 个答案:

答案 0 :(得分:1)

似乎fs.readFile希望将回调作为第三个参数。尝试使用utils.promisify [link]来推广它。 例子

        .then(data => {
            const util = require('util');
            const readFilePromise = util.promisify(readFile);
            return readFilePromise("./sample/Duration_Suite.json", "utf8");
        })

答案 1 :(得分:0)

当我使用copyreadFile的模拟版本时,只要调用适当的回调,代码就可以正常工作。尝试运行下面的代码段。

如果您收到Cannot read property 'then' of undefined,则意味着CopyFolder必须返回undefined,由于返回新的Promise,这似乎是不可能的。

您是否可能致电generateReport().then(...),这就是错误的原因。请注意,generateReport本身不会返回承诺。它什么也不返回,表示undefined。要解决此问题,您应该返回copyFolder返回的承诺。下面的第二个代码段可以做到这一点,并且运行时不会出现错误。

显示该问题的拳头代码段

const fs = {
  copy: (s,d,cb) => cb(null, `copy data: ${s} ${d}`),
  readFile: (s,cb) => cb(null, `readFile ${s}`)
}
let callcount = 0;

const generateReport = () => {
  const copyFolder = (src, dest) => {
    return new Promise((res, rej) => {
      fs.copy(src, dest, (err, data) => {
        if (err) {
          return rej(err);
        }
        return res(data);
      });
    });
  };

  const readFile = src => {
    return new Promise((res, rej) => {
      fs.readFile(src, (err, data) => {
        if (err) {
          return rej(err);
        }
        return res(data);
      });
    });
  };

  // >>> BAD - no return statement here 
  copyFolder("./sample/", "./login/sample/")
    .then(data => {
      return readFile("./sample/Duration_Suite.json", "utf8");
    })
    .then(data => {
      console.log(`call #${++callcount}: ${data}`);
    });
};
console.log("First call without '.then'");
// first call will output data later since there are timeouts
generateReport();
console.log("Now call with '.then'");
// using .then after will give the error you see
generateReport().then(() => console.log("this fails"));

带有修复的第二个片段

const fs = {
  copy: (s,d,cb) => cb(null, `copy data: ${s} ${d}`),
  readFile: (s,cb) => cb(null, `readFile ${s}`)
}
let callcount = 0;

const generateReport = () => {
  const copyFolder = (src, dest) => {
    return new Promise((res, rej) => {
      fs.copy(src, dest, (err, data) => {
        if (err) return rej(err);
        return res(data);
      });
    });
  };

  const readFile = src => {
    return new Promise((res, rej) => {
      fs.readFile(src, (err, data) => {
        if (err) return rej(err);
        return res(data);
      });
    });
  };

  // >>> FIX - return copyFolder's promise
  return copyFolder("./sample/", "./login/sample/")
    .then(data => readFile("./sample/Duration_Suite.json", "utf8"))
    .then(data => console.log(`call #${++callcount}: ${data}`));
};
console.log("Call with '.then'");
generateReport().then(() => console.log("this worked!"));
console.log("This gets printed before the promise completes");