2017-12-03 290 views
0

我很困惑,爲什麼這個代碼返回承諾的數組,而最後一位返回的實際數據(對象數組):異步()伺機返回,而不是數據無極

(async() => { 
 
    \t \t const [user, posts] = await Promise.all([ 
 
    \t \t \t fetch('https://jsonplaceholder.typicode.com/users'), 
 
    \t \t \t fetch('https://jsonplaceholder.typicode.com/posts') 
 
    \t \t ]).then(([res,res2]) => [res.json(),res2.json()] 
 
    \t \t).then(([d1,d2]) => { 
 
    \t \t \t console.log(d1,d2); 
 
    \t }); 
 
    })(); 
 
// Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: Array(10)} 
 
// Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: Array(100)}

當我用自己取,我得到的數據我想:

fetch('https://jsonplaceholder.typicode.com/posts') 
 
\t .then((res) => res.json()) 
 
\t .then((data) => console.log(data)); // returns array of objects 
 

 
// (100) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, ...

回答

3

res.json()返回另一個承諾,因此您必須在承諾鏈中返回承諾或使用await.then()承諾。因爲您使用[res.json(), res2.json()]作爲承諾鏈中的返回值,所以您隱藏了該數組中的承諾,因此根本沒有等待承諾鏈。承諾本身成爲退貨的結果,因此Promise.all()不知道他們在那裏,並沒有等待他們。

我想每個res.json()建議鏈它自己的父:

(async() => { 
     const [user, posts] = await Promise.all([ 
      fetch('https://jsonplaceholder.typicode.com/users').then(res => res.json()), 
      fetch('https://jsonplaceholder.typicode.com/posts').then(res => res.json()) 
     ]); 
     console.log(users, posts); 
    }); 
})(); 

然後,你直接鏈接各res.json()其來源承諾其Promise.all()會那麼對你等待。

僅供參考,我看不出有任何理由要在這裏使用async/await在所有你可以只是這樣做:

Promise.all([ 
     fetch('https://jsonplaceholder.typicode.com/users').then(res => res.json()), 
     fetch('https://jsonplaceholder.typicode.com/posts').then(res => res.json()) 
    ]).then(([users,posts]) => { 
      console.log(users, posts); 
    }); 

僅供參考,它肯定似乎是一個簡單的輔助功能將是有益的太:

function fetchJSON(req) { 
    return fetch(req).then(res => res.json()); 
} 

然後,你可以只是做:

Promise.all([ 
    fetchJSON('https://jsonplaceholder.typicode.com/users'), 
    fetchJSON('https://jsonplaceholder.typicode.com/posts') 
]).then(([users,posts]) => { 
     console.log(users, posts); 
}); 

而且,您可能需要使用所有這些選項進行錯誤處理,以便查看錯誤。您可以使用.catch()或使用try/catch環繞您的​​await

+0

@ jfriend00這很有意義。謝謝。我在https://hackernoon.com/javascript-hacks-for-es6-hipsters-67d633ce8ace上看到了這個「ES6時尚人士的JavaScript黑客」中的例子,我想我會試試。 雖然一個快速筆記。此代碼現在返回「未捕獲(承諾)TypeError :(中間值)不可迭代」 – rsilva

+0

@rsilva - 哪些代碼返回該錯誤? – jfriend00

+0

您在上面提供的那個。 – rsilva

2

問題是數組而不是承諾返回.then(([res,res2]) => [res.json(),res2.json()],因爲json()響應方法返回另一個承諾。這導致在下一個then一系列的承諾。

它應該是

async() => { 
    const [user, posts] = await Promise.all([ 
     fetch('https://jsonplaceholder.typicode.com/users'), 
     fetch('https://jsonplaceholder.typicode.com/posts') 
    ]).then(responses => 
     Promise.all(responses.map(response => response.json())) 
    ); 

    console.log(user, posts); 
} 

注意,添加另一.then(([d1,d2]) => { console.log(d1,d2) })是不必要的,並且也導致錯誤,因爲期待值是未定義的。