集合.map不是一个函数在Promise.all.then中。

4

好的,大家好

我对 promises 还不熟悉,并且正在尝试通过 promises 加载 CSV 文件后映射结果,然后对其进行后续应用。可以使用异步映射吗?在使用 promises 后有其他映射方法吗?还是我太傻了,完全错过了某些简单的东西?

var csv = (url) => new Promise(function(resolve) {
    d3.csv(url, function(data) {
        data.forEach(function(d) { 
            d.String = d.String;
            d.Integer = +d.Integer;
        })
    resolve(data);
    });
});

Promise.all([ 
    csv('content.csv'),
    csv('moreContent.csv')
])
.then(([csvOne, csvTwo]) => { 
    var collection = { csvOne, csvTwo };

    var aveageMap = {};

    collection.map((d,i) => {
        if (!aveageMap[d.String]) {
            aveageMap[d.String] = {
                sum: 0,
                average: 0
            };
        }
        var theWord = aveMap[d.String];
        theWord.sum += +d.Integer;
        theWord.average = theWord.sum / collection.length;
    });

    console.log(aveageMap);

});

对于下面的评论和回答

使用一个数组是一个对象,但返回了两个CSV文件的完整合并... 这影响了theWord.sum / collection.length这一行... 虽然它在某种程度上起作用,但我想使用一个对象数组,这样我就可以得到下面的输出,并在需要时独立访问每个对象。

collection {
    dataCSV {
        String: , Integer: ,
        String: , Integer: ,
    },
    dataCSV2 {
        String: , Integer: ,
        String: , Integer: ,
    }
}

2
我在这里看到两个潜在的问题。1)collection是一个对象,它没有.map()方法。2)你应该在d3.csv的回调函数中调用resolve。现在它在数据准备好之前就已经解决了。 - m0meni
确实,这与承诺本身无关。 - Jared Smith
集合 { } 应该是 对象 还是 数组 集合 [ ] 。您的 JSON 和所使用的术语非常令人困惑。 - Paul Okeke
抱歉问题的表述方式,应该是一个对象。 - FeelingLikeAJabroni
3个回答

1
一些事情:
- 看起来您正在尝试组合csv返回的两个数组,可以通过csvOne.concat(csvTwo)[...csvOne, ...csvTwo](使用es6)来完成。 - 由于您实际上没有在映射函数中返回所有内容,因此更适合使用.forEach。 - 对我来说,d.word看起来应该是d.String(除非它们相同)。还要注意,许多人认为具有大写字母的属性名称很糟糕的风格(特别是那些已经存在类名的属性,如String),因此您可能需要将d.Stringd.Integer重命名为d.stringd.integer或其他更具描述性的名称。看起来ageMap应该是aveageMap
总之,它看起来像:
var csv = (url) => new Promise(function(resolve) {
    d3.csv(url, function(data) {
        data.forEach(function(d) { 
            d.string = d['String'];
            d.integer = +d['Integer'];
        })
        resolve(data);
    });
});
Promise.all([ 
    csv('content.csv'),
    csv('moreContent.csv')
])
.then(([csvOne, csvTwo]) => { 
    var aveageMap = {};
    var collection = [...csvOne, ...csvTwo];
    collection.forEach((d,i) => {
        if (!aveageMap[d.string]) {
            aveageMap[d.string] = {
                sum: 0,
                average: 0
            };
        }
        var theWord = aveageMap[d.string];
        theWord.sum += +d.integer;
        theWord.average = theWord.sum / collection.length;
    });    
    console.log(aveageMap);

});

嗨,谢谢你。我有一个查询,已经附加到问题中了。 - FeelingLikeAJabroni
我已经试过了,它可以工作 - 唯一的问题是 collection.length ... 因为它返回数组的长度,而不是组成数组的对象的长度,如果这有意义的话? - FeelingLikeAJabroni

0

根据我理解你的问题的方式。

Promise.all([csv('content.csv'),csv('moreContent.csv')]).then(([...csvs])=>{
  const collection = {};
  csvs.forEach(csv=>{
    if(!collection[csv.String]) 
      collection[csv.String] = {sum:0, average:0}
      .....
  })
});

0

你不能在非数组对象上调用map方法,如果你想要调用map方法,需要将其转换为array而不是object

var collection = [ csvOne, csvTwo ];

在Javascript中,数组是一个对象。 - connexo
@connexo 是的,但 map 是数组的一个方法。obj = {name: "bob"} 然后跟着 obj.map(x => x) 会给你一个错误。现在试试 [ "bob" ] - VLAZ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接