【问题标题】:What is wrong with this code that promisify a function?这段承诺函数的代码有什么问题?
【发布时间】:2015-11-07 21:03:10
【问题描述】:

此函数不返回承诺。

它使用 csvtojson 模块。 https://www.npmjs.com/package/csvtojson

var CSVConverter=require("csvtojson").Converter;

function get_json(cvs_file_location)
{
    var data=fs.readFileSync(cvs_file_location).toString();
    var csvConverter=new CSVConverter();

    csvConverter.fromString(data,function(err,jsonObj){
        if (err){
            console.log("error msg: " + err);
            return null;
        }

        var json_csv = clone_obj(jsonObj);
        console.log(json_csv);
        return json_csv;
    });
}

我想将它转换成一个返回一个承诺。这是我写的;

var Promise = require('bluebird');
var Converter = Promise.promisifyAll(require("csvtojson").Converter);

function get_json(cvs_file_location)
{
    var data=fs.readFileSync(cvs_file_location).toString();

    return new Converter().fromStringAsync(data)
        .then(function(csvString){
            var json_csv = clone_obj(csvString);
            console.log(json_csv);
            return json_csv;
        })
        .catch(function(cb) {
            console.log("error msg: " + cb);
            return null;
        });
}

不幸的是,它不起作用。错误信息如下所示;

return new Converter().fromStringAsync(data)
                       ^ TypeError: (intermediate value).fromStringAsync is not a function

代码有什么问题?或者有没有其他方法可以编写代码来返回一个承诺?

【问题讨论】:

  • 如果将new Converter() 用括号括起来会怎样:(new Converter()).fromStringAsync
  • 很遗憾,还是同样的错误
  • fromStringAsync 方法在该模块中不存在
  • "我以为 promisifyAll 会在模块中添加 fromStringAsync 方法?" - Promise.promisifyAll(require("csvtojson").Converter) 将只承诺 Converter 的静态方法,而不是使用 new Converter(); 创建的实例的方法。尝试承诺 Converter 的原型 var Converter = require("csvtojson").Converter; Promise.promisifyAll(Converter.prototype);。如果这不起作用,那么您将不得不在创建每个实例后对其进行承诺,除非有办法使用单个实例,否则这样做会很昂贵。
  • 另外,请记住.promisifyAll() 是有选择性的。它会嗅出可以应用的方法,而让其他方法独处。你确定.fromString() 会答应吗?

标签: javascript node.js bluebird


【解决方案1】:

你必须承诺Converterprototype 因为它是一个构造函数。如果 Converter 对象直接具有要承诺的功能(大多数 API 就是这种情况),则常规 var Converter = Promise.promisifyAll(require('csvtojson').Converter)); 将起作用。

var fs = require('fs');
var Promise = require('bluebird');
var Converter = require('csvtojson').Converter;
Promise.promisifyAll(Converter.prototype);

var converter = new Converter();
converter.fromStringAsync(fs.readFileSync('foo.csv', 'utf8'))
  .then(console.log)

【讨论】:

  • 我爱你。我希望我能给你100票!代码现在可以工作了。
  • 我问了一个后续问题。 stackoverflow.com/questions/33582172/…
  • 呃,Bluebird.promisifyAll 确实会自动跟随 .prototype 链接,不是吗?
  • @Bergi,显然不是。我也很惊讶。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-16
  • 2015-04-25
  • 2018-09-09
相关资源
最近更新 更多