【问题标题】:Asynchronous function calls inside for loop in javascriptjavascript中for循环内部的异步函数调用
【发布时间】:2017-09-24 17:06:55
【问题描述】:

写一个像检查机器人一样的小型 Instagram。

它的工作原理是,我有一个对象,它是聊天中的用户列表及其 instagram 用户名。

所以我在这里有一小段代码,它遍历列表,获取每个用户名的最新媒体帖子的喜欢者,然后继续检查,所有这些都在循环中。然而,我面临的问题是循环内部存在异步调用,并且循环不断迭代,但异步调用的结果稍后出现。但是,这不是我想要的操作方式。有人可以告诉我如何克服这个问题,或者以异步方式做到这一点的正确方法吗?谢谢 下面是我的代码,其中还有一条注释显示了列表对象的格式,以防万一有人想知道。谢谢

bot.on('/check', (msg) => {
    list['12345'] = {username:'someguy', list:['@the.haider.ali']};
    list['45678'] = {username:'someguy2', list:['@vishnuvayala']};
    if(list.length != 0){
        for(i in list){
            var list2 = JSON.parse(JSON.stringify(list));
            delete list2[i];
            for(x in list2){
                for(y in list2[x].list){
                    let checkis = list2[x].list[y]
                    console.log("Checking "+checkis);
                    getInstaID(checkis).then(function(userid){
                        return getMediaID(userid);
                    }).then(function(mediaid){
                        return getLikers(mediaid);
                    }).then(function(likers){
                        console.log("Last liker is "+likers[0].username);
                    });
                    console.log("Done checking "+checkis);
                }
            }
        }
    }
});

这是我得到的输出

Checking @the.haider.ali
Done checking @the.haider.ali
Checking @vishnuvayala
Done checking @vishnuvayala
Last liker is ghetto._boy
Last liker is dk.gayathri

【问题讨论】:

  • 您需要以异步方式执行此操作,您正在混合同步和异步
  • @RahulSingh 是的,我自己得出了这个结论,请您至少提出建设性意见吗?
  • 你检查了我的答案,对你有用吗?

标签: javascript node.js for-loop asynchronous instagram


【解决方案1】:

尝试异步等待。异步函数可以被 await/promise 阻塞,数组迭代可以被阻塞直到等待响应。

不要害怕 Await 表达式。它只会阻塞函数,直到同样众所周知的 Promise 无法解决。

请检查它是否有效。

bot.on('/check', async function(msg){
    list['12345'] = {username:'someguy', list:['@the.haider.ali']};
    list['45678'] = {username:'someguy2', list:['@vishnuvayala']};
    if(list.length != 0){
        for(i in list){
            var list2 = JSON.parse(JSON.stringify(list));
            delete list2[i];
            for(x in list2){
                for(y in list2[x].list){
                    let checkis = list2[x].list[y]
                    console.log("Checking "+checkis);
                    var userid = await getInstaID(checkis);
                    var mediaid = await getMediaID(userid);
                    var likers = await getLikers(mediaid);
                    console.log("Last liker is "+likers[0].username);
                    console.log("Done checking "+checkis);
                }
            }
        }
    }
});

输出应该是这样的

Checking 0
Last liker is likers: 0
Done checking 0
Checking 1
Last liker is likers: 1
Done checking 1
Checking 2
Last liker is likers: 2
Done checking 2

【讨论】:

  • 这也将与 async await 在幕后的承诺相同,唯一的事情是控制台日志将是正确的,因为问题有一个控制台日志在承诺中,一个在外面
  • 我在上面的评论中提到这只是因为在你的问题中你正在记录一个内部 promsie 和另一个外部,否则你将日志放在承诺中它的行为将相同 @HaiderAli
猜你喜欢
  • 2015-11-14
  • 1970-01-01
  • 2017-12-16
  • 2012-10-31
  • 2021-09-11
  • 2014-07-09
  • 1970-01-01
  • 2019-04-07
  • 1970-01-01
相关资源
最近更新 更多