Node.js如何将数组索引传递给异步函数

Posted

技术标签:

【中文标题】Node.js如何将数组索引传递给异步函数【英文标题】:Node.js how to pass array index to asynchronous function 【发布时间】:2020-05-22 15:31:55 【问题描述】:

我无法理解如何正确设置承诺/异步函数以按我的意愿执行。我知道 HTTP 请求是异步的,所以当 HTTP 请求发生时 for 循环将继续运行。因此,在 http 请求中执行操作时,我无法访问事件信息(eventName、eventDate)。我可以从请求中访问我的数组,但我的索引是 2(0 和 1 只是有效条目),因为循环已经完成。如何传递我的索引以在 http 请求中使用?如果这是不可能的,我怎样才能在完成 for 循环之前获得我的 API 响应?我尝试让 HTTP 请求等待响应,但是函数的嵌套让我很难做到这一点。任何帮助将不胜感激。

var CronJob = require('cron').CronJob;
const  Client, RichEmbed, Discord  = require('discord.js');
const  config  = require('dotenv');
const fetch = require('node-fetch');
var discord = require('discord.js');

const client2 = new discord.Client();

var rp = require('request-promise');

const MongoClient = require('mongodb').MongoClient;
const uri = "URI";
const dbClient = new MongoClient(uri,  useNewUrlParser: true );

const https = require("https");

const client = new Client(
    disableEveryone: true
);


config(
    path: __dirname + "/.env"
);

//prefix

const settings = 
    prefix: '!'
;


client2.on('ready', () => 
    console.log('I am ready!');

    new CronJob('0,30 * * * * *', function()

        dbClient.connect(err => 
            var monitoredEvents = dbClient.db("dbName").collection("collectionName");

            monitoredEvents.find().toArray(function(err, result) 
                if (err)
                
                    console.log("ERROR!!");
                
                else
                
                    var shows = result;

                    var eventName = '';
                    var eventDate = '';

                    var show = '';

                    for(var index = 0; index < shows.length; index++)
                    
                        eventName = shows[index].eventName;
                        eventDate = shows[index].eventDate;

                        show = shows[index];



                        const url = `URL`;

                        https.get(url, res => 
                            res.setEncoding("utf8");
                            let body = "";
                            res.on("data", data => 
                                body += data;
                            );
                            res.on("end", () => 
                                body = JSON.parse(body);

                                facets = body.facets;

                                function myfunction(arr) 
                                    return arr.map(function(e) 

                                        return 
                                            section: e.section,
                                            count: e.count
                                        ;
                                    );
                                

                                let myMap = new Map();


                                //get newArray which contains sections and count.
                                let newArray = myfunction(facets);

                                //take newArray and combine same sections
                                const out = newArray.reduce((a, o) => 
                                    if (a[o.section]) 
                                        a[o.section].count += o.count
                                     else 
                                        a[o.section] = o
                                    
                                    return a
                                , )


                                let num = Object.values(out);


                                var output = [];
                                var totalCount = 0;

                                for(var j = 0; j < num.length; j++)
                                
                                    output[j] = num[j].section + ' (' + num[j].count + ')';
                                    totalCount += parseInt(num[j].count);
                                

                                var outputString = output.join("\n");

                                if(alertValue >= totalCount)
                                

                                    var guild = client2.guilds.get('guildID');
                                    if(guild && guild.channels.get('channelID'))

                                        guild.channels.get('channelID').send(eventName + " on " + eventDate + " has only " + totalCount + " tickets remaining").then();







                                     else 
                                        console.log("nope");
                                    
                                
                                else
                                    console.log("alert threshhold not met for "+ eventName);
                            );
                        );
                    
                
            );

        );
    , null, true, "America/Los_Angeles");
);


client2.login("discordToken")

【问题讨论】:

如果你简化了你的代码,它会让别人更容易帮助你,以便在不臃肿的情况下重现同样的问题。 @silencedogood 我开始这样做,但如果不删除 client2.on 或 cronjob,我找不到简化的方法。我认为这两者都可以在我需要如何构建其余代码方面发挥重要作用。如果您对如何简化它有任何想法,请告诉我。我想让别人更容易提供帮助,但我担心如果我更改代码,我会给自己和任何查看代码的人带来更多问题 【参考方案1】:

您可以创建一个单独的函数来处理获取请求。 这是一个例子

const createGetAPI = (showObject, URL) => 
    if (showObject && showObject.eventName && showObject.eventDate) 
        https.get(URL, (req, res) => 
            console.log('Do your all operations here');
        );
    
;

dbClient.connect(err => 
    var monitoredEvents = dbClient.db("dbName").collection("collectionName");

    monitoredEvents.find().toArray(function (err, result) 
        if (err) 
            console.log("ERROR!!");
        
        else 
            let shows = result;
            let show = '';

            for (let index = 0; index < shows.length; index++) 
                eventName = shows[index].eventName;
                eventDate = shows[index].eventDate;
                const url = `someurl/somepath/$index`;

                createGetAPI(shows[index], url);
            
        
    

【讨论】:

以上是关于Node.js如何将数组索引传递给异步函数的主要内容,如果未能解决你的问题,请参考以下文章

Node.js:如何将向量传递给函数?

如何使用 promise 将数组从我的模块返回到我的 API?异步函数和承诺 - Node.js

将参数传递给 Node.js 异步瀑布

Node.js如何将geojson从mongodb传递给我可以在前端使用的对象

如何在 node.js 环境中将查询语句传递给 bigquery

将 c++ 双缓冲区传递给 Node Js(直接)[Node JS : V8 c++ : Nan]