为什么地图不起作用但是foreach是?

Eri*_*rik 5 google-maps dart angular-dart

forEach很好用

var newMarkers = new List<Marker>();
providers.forEach((p) {
  var marker = markerFrom(p);
  newMarkers.add(marker);
  print("got one");
});

_markers = newMarkers;
Run Code Online (Sandbox Code Playgroud)

但是map当放置在与以下内容完全相同的位置时,这不会被调用forEach:

_markers = providers.map((p) => markerFrom(p));
Run Code Online (Sandbox Code Playgroud)

另外,这是markerFrom方法:

  Marker markerFrom(FoodProvider provider) {
  var marker = new Marker(new MarkerOptions()
    ..map = _map
    ..position = new LatLng(provider.latitude, provider.longitude)
    ..title = provider.name
    ..icon = 'http://maps.google.com/mapfiles/ms/icons/red-dot.png'
  );

  var infoWindow = new InfoWindow(new InfoWindowOptions()..content = marker.title);

  marker.onClick.listen((e) {
    infoWindow.open(_map, marker);
  });

  return marker;
}
Run Code Online (Sandbox Code Playgroud)

lrn*_*lrn 8

map功能上Iterable懒惰.它只是在原始文件周围创建一个包装器Iterable,但在开始迭代之前它实际上并没有做任何事情.

这是一件好事,即使你习惯了map其他语言的热切功能也会令人惊讶.这意味着您可以在以下迭代项上组合操作:

listOfStrings
    .map((x) => complicatedOperationOnString(x))
    .take(2)
    .forEach(print);
Run Code Online (Sandbox Code Playgroud)

这只对前两个字符串进行了复杂的操作.

如果你想要一个标记列表,你需要在以下toList后面调用map:

_markers = providers.map(markerFrom).toList();
Run Code Online (Sandbox Code Playgroud)

一般来说,当传递给函数时,你应该非常小心,这种map副作用只发生一次.如果你map多次迭代结果,每次都会发生这种效果,所以如果你这样做了:

_markers = providers.map(markerFrom);
int count = _markers.length;
_markers.forEach((marker) { doSomething(marker); });
Run Code Online (Sandbox Code Playgroud)

你会冒险的副作用发生两次,一次length和一次forEach,这两个迭代_markers.它并不总是发生(有些迭代物在length没有实际迭代的情况下知道它们),但它总是存在风险.在这些情况下,要么使用forEach副作用是你唯一的副作用,要么立即toList强制执行所有操作,然后只查看结果列表.