Why is my setTimeout function in JavaScript not executing multiple download rounds correctly?

I am trying to download multiple files sequentially in a JSP page using setTimeout and top.location.href, but the download process doesn’t behave as expected. Instead of executing each download in separate rounds (with a 2-second delay), it seems like it only processes the first file and skips the others.

Here’s a simplified version of my code:

<%@page language="java"%>
<%@ page import="java.util.*, java.text.*, java.sql.*"%>
<%@ page import="java.io.*"%>
<%@ page import="sapphire.accessor.QueryProcessor, sapphire.util.DataSet, sapphire.util.StringUtil, sapphire.util.ActionBlock, sapphire.accessor.ActionProcessor, sapphire.util.DBAccess, sapphire.accessor.ActionException"%>
<%@ taglib uri="/WEB-INF/tlds/sapphire.tld" prefix="sapphire" %>
<%@ taglib uri="/WEB-INF/tlds/c.tld" prefix="c" %>
<sapphire:controlledpage allowanonymous="true"/>
<sapphire:page layout="${layout.objectname}">
<sapphire:pagecontent name="content">

<%!
    public void writeLog(String logstr) {
        String pathFile = "D:\GenControlChartLog.txt";
        try {
            PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(pathFile, true)));
            out.println(new java.util.Date() + " - " + logstr);
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
%>

<%
    writeLog("Start processing control charts");
    String data = requestinfo.getProperty("data");
    String sdate = requestinfo.getProperty("sdate");
    String edate = requestinfo.getProperty("edate");
    String scno = requestinfo.getProperty("scno");
    String[] _data = data.split("%3B");
    String filenameall = "";
    for(int i = 0;i<_data.length;i++) {
        String[] __data = _data[i].split(";");
        String filename = "ControlChart-"+__data[0]+"-"+i+"-" + new SimpleDateFormat("dd-MM-yyyy-HH-mm-ss").format(new java.util.Date()) +".xlsx";
        String success = "";
        writeLog("filename = "+ filename);
        HashMap hm = new HashMap();
        hm.put("filename", filename);
        hm.put("keyid1", _data[i]);
        hm.put("sdate", sdate);
        hm.put("edate", edate);
        hm.put("scno", scno);
        ActionProcessor ap = new ActionProcessor(application.getInitParameter("nameserverlist"), pageinfo.getConnectionId());
        try {
            ap.processAction("ControlChartXLXS", "1", hm);
            success = "SUCCESS";    
            writeLog("ControlChartXLXS SUCCESS ");
        } catch (ActionException ae) {
            success = "FAILURE";
            writeLog("error1 :"+ae.getMessage());
        } catch (Exception e) {
            success = "FAILURE";
            writeLog("error2 :"+e.getMessage());
        }
        if(i>0) {
            filenameall +="%3B";
        }
        filenameall +=filename;
    }
%>

<script>
    function downloadFile_V2(file, i) {
        setTimeout(function() {
            top.sapphire.alert( 'into setTimeout Download round ' + i, true );
            console.log('into setTimeout Download round ' + i);
            top.location.href = "WEB-CUSTOM/Download/DownloadFile_00.jsp?filepath=WEB-CUSTOM/ControlChart/Output/" + file;
        }, i * 2000); 
    }

    var _filename = "<%=filenameall%>";
    console.log('filearrOG = ' + _filename);
    if (_filename != "") {
        var filearr = _filename.split("%3B");
        console.log('filearr after split = ' + filearr);
        top.sapphire.alert('filearr length = ' + filearr.length, true);
        for (let i = 0; i < filearr.length; i++) {
            top.sapphire.alert('filearr = ' + filearr[i], true);
            console.log('filearr = ' + filearr[i]);
            downloadFile_V2(filearr[i], i);
        }
    } else {
        top.sapphire.alert('Not Found Document Template!', true);
    }
</script>

</sapphire:pagecontent>
</sapphire:page>

Problem:

The downloadFile_V2 function is supposed to trigger downloads sequentially, with a 2-second delay between each round. However, only the first download occurs, and the others are skipped or not triggered.

I expect the logs to show
into setTimeout Download round 0
into setTimeout Download round 1
into setTimeout Download round 2

But instead, it only logs the first round (into setTimeout Download round 0).
What I’ve tried:

Used setTimeout with a delay of i * 2000 for each download.
Checked the length of the filearr array, and it seems correct.
Checked for any JavaScript errors, but none are shown.
Any suggestions on why this might be happening or how I can fix this?