2016-04-25 61 views
-1

所以我有[从其中一个例子来到Font Face Observer Github]如何在JavaScript动态撰写迭代函数数组

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'); 
}); 

下面的代码我想以这样的方式重写这一点,我可以使用push以动态方式组成包含[并执行]功能的阵列,即[fontA.load(), fontB.load()]

这是我到目前为止。

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的工作,所以阵列的map方法未必可行。

UPDATE

我能找到利用@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,以便解决浏览器的需求。

+0

到底是什么错你的第二个实施? – jfriend00

+0

正如问题中提到的,有一个验证警告 –

+0

那么,您的整个问题关于验证警告?如果是这样,请改变标题以反映这一点,并确保在问题中明确说明。现在,我们无法真正知道你在问什么。 – jfriend00

回答

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')); 
+0

'Promise.all()'期待一个实际的承诺数组作为它的参数,所以你不需要这里的'.apply()'。我认为你的答案很好,你只需要使用'Promise.all()'而不是'Promise.all.apply()'。 – jfriend00

+0

@ jfriend00谢谢,但现在我真的不明白这个问题。我修改了答案,但不知何故,我不认为这是OP所要求的。 –

+0

是的,这就是为什么我要求OP澄清他们的第二个代码块有什么问题。我也不确定。 – jfriend00

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 
});