学习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
);