2017-12-03 204 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) })是不必要的,并且也导致错误,因为期待值是未定义的。