TypeError: Cannot call method 'then' of undefined in Nodejs Promises

TypeError: Cannot call method 'then' of undefined in Nodejs Promises

你能解释一下下面这段代码有什么问题吗?

   var promise = fs.readFile(file);

   var promise2 = promise.then(function(data){
      var base64 = new Buffer(data, 'binary').toString('base64');
      res.end("success");
   }, function(err){
      res.end("fail");
   });

其抛出错误为TypeError: Cannot call method 'then' of undefined

readFile 没有 return 承诺。 NodeJS 大体上早于 promises 的广泛使用,并且主要使用简单的回调。

要读取文件,请传入一个简单的回调,如文档中的示例所示:

fs.readFile('/etc/passwd', function (err, data) {
  if (err) throw err;
  console.log(data);
});

有一个 promisify-node module 可用,它将标准的 NodeJS 模块包装在一个支持 promise 的 API 中。其文档中的示例:

var promisify = require("promisify-node");
var fs = promisify("fs")
fs.readFile("/etc/passwd").then(function(contents) {
  console.log(contents);
});

我应该强调一下,我不知道也没有用过它,所以我不能说它的工作有多好。它似乎使用 nodegit-promise"Bare bones Promises/A+ implementation with synchronous inspection" 而不是 JavaScript 的 Promise(这很公平;它早于 JavaScript 的 Promise 几年了)。

您必须创建一个异步函数,其中 returns 一个 promise 或使用像 bluebird.js

这样的 promise 库

原版 JS

 var promise = readFileAsync();
    promise.then( function(result) {
        // yay! I got the result.
    }, function(error) {
        // The promise was rejected with this error.
    }

    function readFileAsync()
    {
       var promise = new Promise.Promise();
       fs.readFile( "somefile.txt", function( error, data ) {
            if ( error ) {
                promise.reject( error );
            } else {
                promise.resolve( data );
            }
        });

        return promise;
    }

和BlueBird.js

 var Promise = require("bluebird"); 
 var fs = Promise.promisifyAll(require("fs"));

    fs.readFileAsync("myfile.json").then(JSON.parse).then(function (json) {
        console.log("Successful json");
    }).catch(SyntaxError, function (e) {
        console.error("file contains invalid json");
    }).catch(Promise.OperationalError, function (e) {
        console.error("unable to read file, because: ", e.message);
    });