Edit2:底部的解决方案
我正在使用chrome-console,我正在尝试输出提取的数据,而我只是通过在正确的位置写“await”来获得所需的输出,即使另一个解决方案可以提前做到,我不知道为什么/这个怎么运作。
solution()是我正在做的网络课程的“官方”解决方案。目前,这两个函数返回相同的函数。在myFunction中,我尝试在每个使用过的函数前写“await”并使每个函数“异步”,但我仍然不能替换日志中的“await”,即使其他解决方案可以。
const urls = ['https://jsonplaceholder.typicode.com/users']
const myFunction = async function() {
// tried await before urls/fetch (+ make it async)
const arrfetched = urls.map( url => fetch(url) );
const [ users ] = arrfetched.map( async fetched => { //tried await in front of arrfetched
return (await fetched).json(); //tried await right after return
});
console.log('users', await users); // but can't get rid of this await
}
const solution = async function() {
const [ users ] = await Promise.all(urls.map(async function(url) {
const response = await fetch(url);
return response.json();
}));
console.log('users', users); // none here, so it can be done
}
solution();
myFunction();
我认为“等待”的工作原理如下:
const a = await b;
console.log(a); // this doesn't work
同样的
const a = b;
console.log(await a); // this works
但它没有,我不明白为什么不。我觉得Promise.all做了一些意想不到的事情,因为简单地在声明中写“await”不能做同样的事情,只有在声明之后。
Edit1:这不起作用
const myFunction = async function() {
const arrfetched = await urls.map( async url => await fetch(url) );
const [ users ] = await arrfetched.map( async fetched => {
return await (await fetched).json();
});
console.log('users', users);
}
Edit2:感谢大家的帮助,我尝试将“.toString()”放在很多变量上并切换到我在代码中放置“等待”的地方,而不是。据我了解,如果我不使用Promise.all那么我需要等待每次我想要使用(如在实际数据中,而不仅仅是使用)一个有承诺的函数或变量。仅仅等待数据被采购的地方是不够的,而不是更进一步。在上面的Edit1中,用户运行bevore任何其他await完成,因此无论我写入多少等待,都没有执行。在(在我的案例中为chrome-)控制台中复制此代码很好地证明了这一点:
const urls = [
'https://jsonplaceholder.typicode.com/users',
]
const myFunction = async function() {
const arrfetched = urls.map( async url => fetch(url) );
const [ users ] = arrfetched.map( async fetched => {
console.log('fetched', fetched);
console.log('fetched wait', await fetched);
return (await fetched).json();
});
console.log('users', users);
console.log('users wait', await users);
}
myFunction();
// Output in the order below:
// fetched()
// users()
// fetched wait()
// users wait()
TL; DR:Promise.all
在那里非常重要,但这并不神奇。它只是将一个Promises数组转换为一个用数组解析的Promise。
让我们打破myFunction
:
const arrfetched = urls.map( url => fetch(url) );
这将返回一个Promises数组,到目前为止一切都很好。
const [ users] = arrfetched.map( async fetched => {
return (await fetched).json();
});
你正在解构数组以获得第一个成员,所以它与此相同:
const arr = arrfetched.map( async fetched => {
return (await fetched).json();
});
const users = arr[0];
在这里,我们将一组承诺转换为另一个承诺数组。请注意,使用map
函数调用async
将始终生成Promises数组。
然后你将该数组的第一个成员移动到users
,所以users
现在实际上包含一个Promise。然后在打印之前等待它:
console.log('users', await users);
相比之下,另一个片段在这里略有不同:
const [ users ] = await Promise.all(urls.map(async function(url) {
const response = await fetch(url);
return response.json();
}));
再一次,我们将解构分开:
const arr = await Promise.all(urls.map(async function(url) {
const response = await fetch(url);
return response.json();
}));
const users = arr[0];
Promise.all
将Promise数组转换为单个Promise,从而生成一个数组。这意味着,在await Promise.all
之后,arr
中的所有东西都在等待(你可以想象await Promise.all
就像一个等待阵列中所有东西的循环)。这意味着arr
只是一个正常的数组(不是Promises数组),因此users
已经等待,或者更确切地说,它从来就不是一个Promise,因此你不需要await
它。
也许最简单的解释方法是分解每一步所达到的目标:
const urls = ['https://jsonplaceholder.typicode.com/users']
async function myFunction() {
// You can definitely use `map` to `fetch` the urls
// but remember that `fetch` is a method that returns a promise
// so you'll just be left with an array filled with promises that
// are waiting to be resolved.
const arrfetched = urls.map(url => fetch(url));
// `Promise.all` is the most convenient way to wait til everything's resolved
// and it _also_ returns a promise. We can use `await` to wait for that
// to complete.
const responses = await Promise.all(arrfetched);
// We now have an array of resolved promises, and we can, again, use `map`
// to iterate over them to return JSON. `json()` _also_ returns a promise
// so again you'll be left with an array of unresolved promises...
const userData = responses.map(fetched => fetched.json());
//...so we wait for those too, and destructure out the first array element
const [users] = await Promise.all(userData);
//... et voila!
console.log(users);
}
myFunction();
Await只能在异步函数中使用。 Await是一个保留密钥。如果它不是异步的话,你不能等待。这就是它在console.log中工作但不在全局范围内的原因。