如何在JavaScript中动态组合可迭代函数数组

时间:2016-04-25 18:39:35

标签: javascript promise

所以我有以下代码[来自Font Face Observer Github]

上的一个示例
var fontA = new FontFaceObserver('Family A');
var fontB = new FontFaceObserver('Family B');

Promise.all([fontA.load(), fontB.load()]).then(function () {
  console.log('Family A & B have loaded');
});

我正在尝试以这样一种方式重写它:我可以使用[fontA.load(), fontB.load()]以动态方式组合包含[并执行]函数的数组,即push

这是我到目前为止所拥有的。

var font_arr = ['Family A', 'Family B'];
var font_item_obj;
var font_load_item_res;
var font_load_arr = [];
for(var i = 0; i < font_arr.length; i++)
{
   font_item_obj = new FontFaceObserver(font_arr[i]);
   font_load_item_res = function(){
      font_item_obj.load();
   };
   font_load_arr.push(font_load_item_res);
}

Promise.all(font_load_arr).then(function () {
    console.log('Family A & B have loaded');
});

控制台消息按预期显示,但我不禁觉得有更好的方法来编写它。另外,我在WebStorm中收到一条警告:Mutable variable is available from closure您有这段代码:font_item_obj.load();

修改

代码需要在IE8上运行,因此Array的map方法可能不可行。

更新

我能够使用@SkinnyJ和@MinusFour的指导找到答案;使用map功能似乎效果最好。这是更新后的代码:

var font_arr = [{'font-family': 'Family A', 'font-options': {}}, {'font-family': 'Family B', 'font-options': {}}];

function loadFont(font_obj)
{
    var font_obj_family_str = font_obj['font-family'];
    var font_obj_options_obj = font_obj['font-options'];

    var font_load_obj = new FontFaceObserver(font_obj_family_str, font_obj_options_obj);
    return font_load_obj.load();
}

Promise.all(font_arr.map(loadFont)).then(function () {
    console.log('Family A & B have loaded');
});

使用font_arr循环创建可迭代对象(在本例中为for)非常容易。另外,我找到了shim for map on IE8 here,以便解决浏览器要求。

2 个答案:

答案 0 :(得分:2)

您可以在动态创建的数组上使用Array.prototype.map吗?

var fonts = [];
fonts.push('Family A');
fonts.push('Family B');

Promise.all(fonts.map(font => new FontFaceObserver(font).load()))
  .then(() => console.log('Family A & B have loaded'));

答案 1 :(得分:2)

使用map

更容易
var font_arr = ['Family A', 'Family B'],
    font_objs = font_arr.map(fm => new FontFaceObserver(fm));

Promise.all(font_objs.map(obj => obj.load())).then(function(){
    //all loaded
});