学习Promises,Async/Await控制执行顺序
Learning Promises, Async/Await to control execution order
我一直在研究 promises、await 和 async 函数。当我刚刚在学习 promises 阶段时,我意识到以下几点:当我发出两个请求时,无法保证它们会按照代码中编写的顺序出现。当然,路由和数据包是一个网络。当我 运行 下面的代码时,请求将不按特定顺序解析。
const getCountry = async country => {
await fetch(`https://restcountries.com/v2/name/${country}`)
.then(res => res.json())
.then(data => {
console.log(data[0]);
})
.catch(err => err.message);
};
getCountry('portugal');
getCountry('ecuador');
此时,我还没有了解 async 和 await。所以,下面的代码完全按照我想要的方式工作。每个请求,等到另一个请求完成。
这是最简单的方法吗?有没有我可以删除的冗余?我不需要大量的替代示例;除非我做错了什么。
await fetch(`https://restcountries.com/v2/name/${country}`)
.then(res => res.json())
.then(data => {
console.log(data[0]);
})
.catch(err => err.message);
};
const getCountryData = async function () {
await getCountry('portugal');
await getCountry('ecuador');
};
getCountryData();
提前致谢,
我按照@deceze 推荐的方式进行了尝试,效果很好:我删除了所有 .then
并用 await
替换了它们。这样就干净多了。现在我可以使用普通的 try 和 catch 块了。
// GET COUNTRIES IN ORDER
const getCountry = async country => {
try {
const status = await fetch(`https://restcountries.com/v2/name/${country}`);
const data = await status.json();
renderCountry(data[0]); // Data is here. Now Render HTML
} catch (err) {
console.log(err.name, err.message);
}
};
const getCountryData = async function () {
await getCountry('portugal');
await getCountry('Ecuador');
};
btn.addEventListener('click', function () {
getCountryData();
});
谢谢大家
是的,这是正确的方法。请注意,您正在阻止每个请求,因此它们一次 运行 一个,从而导致效率低下。正如我提到的,JavaScript 的美妙之处在于它的异步性,因此请充分利用它。您几乎可以同时 运行 所有请求,从而大大加快您的请求速度。举个例子:
// get results...
const getCountry = async country => {
const res = await fetch(`https://restcountries.com/v2/name/${country}`);
const json = res.json();
return json;
};
const getCountryData = async countries => {
const proms = countries.map(getCountry); // create an array of promises
const res = await Promise.all(proms); // wait for all promises to complete
// get the first value from the returned array
return res.map(r => r[0]);
};
// demo:
getCountryData(['portugal', 'ecuador']).then(console.log);
// it orders by the countries you ordered
getCountryData(['ecuador', 'portugal']).then(console.log);
// get lots of countries with speed
getCountryData(['mexico', 'china', 'france', 'germany', 'ecaudor']).then(console.log);
编辑: 我刚刚意识到 Promise.all
auto-orders 对您的承诺,因此无需添加额外的排序功能。如果你采用不同的方法,这里是 fn 的排序供参考:
myArr.sort((a, b) =>
(countries.indexOf(a.name.toLowerCase()) > countries.indexOf(b.name.toLowerCase())) ? 1 :
(countries.indexOf(a.name.toLowerCase()) < countries.indexOf(b.name.toLowerCase()))) ? -1 :
0
);
我一直在研究 promises、await 和 async 函数。当我刚刚在学习 promises 阶段时,我意识到以下几点:当我发出两个请求时,无法保证它们会按照代码中编写的顺序出现。当然,路由和数据包是一个网络。当我 运行 下面的代码时,请求将不按特定顺序解析。
const getCountry = async country => {
await fetch(`https://restcountries.com/v2/name/${country}`)
.then(res => res.json())
.then(data => {
console.log(data[0]);
})
.catch(err => err.message);
};
getCountry('portugal');
getCountry('ecuador');
此时,我还没有了解 async 和 await。所以,下面的代码完全按照我想要的方式工作。每个请求,等到另一个请求完成。
这是最简单的方法吗?有没有我可以删除的冗余?我不需要大量的替代示例;除非我做错了什么。
await fetch(`https://restcountries.com/v2/name/${country}`)
.then(res => res.json())
.then(data => {
console.log(data[0]);
})
.catch(err => err.message);
};
const getCountryData = async function () {
await getCountry('portugal');
await getCountry('ecuador');
};
getCountryData();
提前致谢,
我按照@deceze 推荐的方式进行了尝试,效果很好:我删除了所有 .then
并用 await
替换了它们。这样就干净多了。现在我可以使用普通的 try 和 catch 块了。
// GET COUNTRIES IN ORDER
const getCountry = async country => {
try {
const status = await fetch(`https://restcountries.com/v2/name/${country}`);
const data = await status.json();
renderCountry(data[0]); // Data is here. Now Render HTML
} catch (err) {
console.log(err.name, err.message);
}
};
const getCountryData = async function () {
await getCountry('portugal');
await getCountry('Ecuador');
};
btn.addEventListener('click', function () {
getCountryData();
});
谢谢大家
是的,这是正确的方法。请注意,您正在阻止每个请求,因此它们一次 运行 一个,从而导致效率低下。正如我提到的,JavaScript 的美妙之处在于它的异步性,因此请充分利用它。您几乎可以同时 运行 所有请求,从而大大加快您的请求速度。举个例子:
// get results...
const getCountry = async country => {
const res = await fetch(`https://restcountries.com/v2/name/${country}`);
const json = res.json();
return json;
};
const getCountryData = async countries => {
const proms = countries.map(getCountry); // create an array of promises
const res = await Promise.all(proms); // wait for all promises to complete
// get the first value from the returned array
return res.map(r => r[0]);
};
// demo:
getCountryData(['portugal', 'ecuador']).then(console.log);
// it orders by the countries you ordered
getCountryData(['ecuador', 'portugal']).then(console.log);
// get lots of countries with speed
getCountryData(['mexico', 'china', 'france', 'germany', 'ecaudor']).then(console.log);
编辑: 我刚刚意识到 Promise.all
auto-orders 对您的承诺,因此无需添加额外的排序功能。如果你采用不同的方法,这里是 fn 的排序供参考:
myArr.sort((a, b) =>
(countries.indexOf(a.name.toLowerCase()) > countries.indexOf(b.name.toLowerCase())) ? 1 :
(countries.indexOf(a.name.toLowerCase()) < countries.indexOf(b.name.toLowerCase()))) ? -1 :
0
);