async() 等待返回 Promise 而不是数据

async() await returning Promise instead of data

我很困惑为什么这段代码 returns 一个承诺数组,而最后一位 returns 实际数据(对象数组):

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

当我自己使用fetch时,得到了我想要的数据:

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

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

res.json() return 是另一个承诺,因此您必须 return 承诺链中的承诺或在该承诺上使用 await.then() .因为您使用 [res.json(), res2.json()] 作为承诺链中的 return 值,所以您将承诺隐藏在该数组中,因此承诺链根本不会等待它们。承诺本身成为 return 结果,因此 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

问题是在 .then( ([res,res2]) => [res.json(),res2.json()] 中返回了数组而不是承诺,因为 json() 响应方法 returns 另一个承诺。这会导致下一个 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) }) 是不必要的,并且还会导致错误,因为等待的值未定义。