【问题标题】:How do I execute these 2 different blocks of code in a sequence in JavaScript?如何在 JavaScript 中按顺序执行这两个不同的代码块?
【发布时间】:2021-05-13 05:53:10
【问题描述】:

这是我路线中的代码:

const hotspots = await Hotspot.find({user: req.user._id});
    if(!hotspots) return res.render("hotspot");
    let hotspotData = [];
    let rewards = [];
function getApiData(){
        return new Promise((resolve,reject)=>{
            let error = false;
            for (let hotspot of hotspots){
                axios.get(`https://api.helium.io/v1/hotspots/${hotspot.hotspot}`)
                    .then((resp)=>hotspotData.push(resp.data));
                
                axios.get(`https://api.helium.io/v1/hotspots/${hotspot.hotspot}/rewards/sum`)
                    .then((resp)=> {
                        console.log("first console log",resp.data.data.total)
                        rewards.push(resp.data.data.total) ;
                        console.log("Data gained from axios",resp.data.data.total);
                    })
                
            }
            if(!error) resolve();
            else reject("Something went wrong");
        })
    }

 getApiData().then(()=> {
        console.log(hotspotData);
        console.log(rewards);
        res.render("hotspot",{hotspots: hotspotData, rewards: rewards});
    });

其他一切都很好,但是当我记录 hotspotDatarewards 时,我得到了一个空数组,但正如你所见,我已经将我从 API 获得的数据分别推送到了这些数组。但是 sti;;我得到空数组。请帮我。我已经记录了 API 数据,是的,它正在发送正确的数据,但我不知道为什么这些数据没有被推送到数组中。

编辑:这是表明我的代码没有按照我想要的方式执行的输出:

【问题讨论】:

  • 检查事件循环是如何工作的,以及如何使用 async/await 代替 Promise,它也会让你的代码更容易阅读
  • 这种承诺方法运行良好。只是数据没有被推送到数组中,我想知道为什么
  • 它不起作用,因为promise方法不起作用嘿嘿让我在答案中写几个例子,给我一点时间

标签: javascript node.js asynchronous promise


【解决方案1】:

这里发生的是,发回响应的代码在 axios 响应到达之前执行:

  • 首先,使用异步/等待方法调用数据库(对吗?)。
  • 然后定义一个返回 Promise 的函数并调用它来处理 then() 函数中的响应。
  • 当 Promise 为 resolve()d 时执行那段代码(注意没有代码可以处理被拒绝的响应)。
  • 现在,一旦for 循环结束,promise 就会得到解决,它不会等待 对于 axios 承诺返回,它只是触发请求和 继续。 它们返回后的代码块将在稍后运行。

如果你想解决这个问题,你可以做的一件事是在任何地方使用 async/await,并按顺序进行调用,如下所示:

const hotspots = await Hotspot.find(...);

function async getApiData() {
    let hotspotData = [];
    let rewards = [];
    for loop {
        hotspot = await axios.get(hotspot)
        reward = await axios.get(reward)
        ...
        // add both to the arrays
    }
    return { hotspotData, rewards }
}

const { hotspotData, rewards } = await getApiData();
console.log(hotspotData);
console.log(rewards);
res.render("hotspot",{hotspots: hotspotData, rewards: rewards});

注意:上面的代码比真正的javascript更伪代码好吗?

我认为这可能是一个有趣的阅读:https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await

另外,请注意所有的 axios 调用似乎是相互独立的,所以也许您可以异步运行它们,并等待所有的 Promise 得到解决以继续。查看更多信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all (首先确保它按顺序工作)

我认为它应该是一系列承诺(每个热点一个,for 循环中的奖励),然后返回类似:

return Promise.all([promise1, promise2, promise3]);

【讨论】:

  • 我试过了,但现在两个数组都未定义。
  • 您知道getApiData() 调用中是否有故障吗?
  • 记住上面的代码不是复制粘贴,是伪代码,只是为了表达想法,好吗?
  • 是的,我知道。我没有复制粘贴。但是两个 api 调用的结果现在都未定义。
  • 你能调试那个代码吗?检查被调用的最终 url 是什么,以及它返回什么
猜你喜欢
  • 2021-03-16
  • 1970-01-01
  • 2011-02-07
  • 1970-01-01
  • 2020-09-05
  • 1970-01-01
  • 1970-01-01
  • 2020-06-06
  • 1970-01-01
相关资源
最近更新 更多