首页 > 解决方案 > Javascript 等待 Promises 返回数据,然后分配 onClick 事件侦听器以对返回的数据执行操作

问题描述

(更新:我现在可以通过使用 async / await 来解决绘制数据的问题,等待承诺解决......但是,现在我面临的问题是如何停止setInterval处于关闭状态的计时器.)

我想完成以下任务:

onLoad 事件监听器:

window.onload = async function () {
   drawChart([]);
   const data = await fetchData(15);
   document.getElementById("start").onclick = () => plotData(data);

   // I want to be able to clearInterval on click of Stop button... but its not working...
   document.getElementById("stop").onclick = clearInterval(plotData);  
};

绘图/获取功能:

const plotData = (data) => {
  let i = 0;
  // How do i clear this interval outside of this function?
  const interval = setInterval( () => {
    i++;
    if (i === data.length) { clearInterval(interval); }
    let newData = data.slice(0,i);
    drawChart(newData); 
    console.log('draw');
  }, 1000);
}

const fetchData = async (times) => {
  let url = `https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-1295/lounging-dog.jpg`;
  const data = [];
  for (let i = 0; i < times; i++) {
    start = (new Date()).getTime();
    await fetch(url)
      .then( res => {
        end = (new Date()).getTime();
        console.log('times', i+1);
        console.log('response milisec', end - start);            
        data.push({ xVal: i+1, yVal: end-start}); 
      })
      .catch( e => console.log(e));   
  }
  return data;
};

我无法理解的是当 setInterval 在回调中定义时如何在窗口上下文中清除Interval。

您还可以查看我的CodePen了解更多信息。

提前致谢!

标签: javascriptpromiseonclickfetches6-promise

解决方案


等待承诺解决使用await

// get fetch call data
const data = await fetchData(10).then( (res) => {
  console.log(res);
});

// assign button onClick handler, data undefined
document.getElementById("start").onclick = drawChart(data);  

一个更好的方法是,不是在开始下一次获取之前等待每个 PromisefetchData解决,而是创建每个 Promise,然后等待所有 Promise。它看起来像这样:

const fetchData = async (times) => {
  const url = 'https://reqres.in/api/users?page=2'
  const promises = [];
  for (let i = 0; i < times; i++) {
    start = (new Date()).getTime();
    promises.push( 
      fetch(url)
      .then( res => {
        end = (new Date()).getTime();
        console.log('times', i+1);
        console.log('response milisec', end - start);            
        return { xVal: i+1, yVal: end-start};
      })
      .catch( e => console.log(e))
     );
  }
  
  let data = await Promise.all(promises);
  console.log(data)

  return data;
};

fetchData(3);


推荐阅读