2016-12-19 174 views
1

我想要fetch多個JSON文件。這是我的代碼:Promise.all過早解決

var timestamps = []; 
var urls = ['assets/layouts/default.json','assets/layouts/simple.json']; 
var jsons = []; 
Promise.all(urls.map(url => { 
    fetch(url) 
    .then(data => data.json()) 
    .then(json => { 
    jsons.push(json); 
    timestamps.push(performance.now()); 
    }); 
})) 
.then(() => { 
    console.log(`All assets loaded. Assets were loaded at: ${timestamps}, this log was made at ${performance.now()}. Loaded data: ${jsons}`); 
} 
); 

問題是,Promise.all似乎過早解決。正如你可以看到我包括一些調試,它會記錄這個:

All assets loaded. Assets were loaded at: , this log was made at 37.73. Loaded data: 

如果我換行console.logsetTimeout和節省時間Promise.all解決像這樣:

.then(() => { 
    let promiseResolvedAt = performance.now(); 
    setTimeout(() => { 
    console.log(`All assets loaded. Assets were loaded at: ${timestamps}, Promise.all was resolved at ${promiseResolvedAt}. Loaded data: ${jsons}`); 
    }) 
} 

我得到這樣的:

All assets loaded. Assets were loaded at: 63.44000000000001,63.555, Promise.all was resolved at 55.96500000000001. Loaded data: [object Object],[object Object] 

我可以得到它通過使用setTimeout工作就像我想它,但我敢肯定有一個更好的辦法,我只是在做事端這裏錯了。

爲什麼在組件承諾解決之前Promise.all已解決?

我在Chrome 55

+0

除去'fetch'語句周圍的'{''}'以允許隱式返回。 – jib

回答

1

您需要返回承諾:

Promise.all(urls.map(url => { 
    return fetch(url) 
    .then(data => data.json()) 
    .then(json => { 
     jsons.push(json); 
     timestamps.push(performance.now()); 
    }); 
})) 

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions#Function_body

箭功能可以有一個 「簡明體」 或慣用的 「塊 體」。

在一個簡潔的主體中,只需要一個表達式,並附有一個隱含的 返回值。 在塊體中,您必須使用明確的return 語句

1

你需要將URL映射的數組時調用返回fetch運行它,否則,你的Promise.all(...)正在等待[undefined, undefined],這將立即解決,當你觀察到。

Promise.all(urls.map(url => { 
    return fetch(url) 
// ^^^^^^ 
    .then(data => data.json()) 
    .then(json => { 
     jsons.push(json); 
     timestamps.push(performance.now()); 
    }); 
}))