首页 > 解决方案 > Javascript for of 循环只运行一次

问题描述

我正在从 API 获取数据,并且由于我必须收集大量数据,因此我使用 setTimeOut 函数将每个请求延迟 3 秒。但是,当我尝试运行代码时,for 循环只运行一次并完成程序。

const fs = require('fs')
const { JSDOM } = require("jsdom")
const { window } = new JSDOM("")
const $ = require("jquery")(window)
const path = require('path')
const fetchArt = require('./utils/fetchArt.js')
const { data } = require('jquery')
const { resolve } = require('path')

let replacer = RegExp(' ', 'g')
let slash = RegExp('/', 'g')

const requestArtSongs = (artist) => {
    return $.getJSON("https://www.vagalume.com.br/" + artist + "/index.js").then(
        function (data) {
            return data.artist.lyrics.item
        }
    )
}

const map = (lang) => {
    switch (lang) {
        case 1: return 'pt'
        case 2: return 'en'
        default: return lang
    }
}

const requestMusic = (artist, song) => {
    return $.getJSON(
        "https://api.vagalume.com.br/search.php"
        + "?art=" + artist
        + "&mus=" + song
        + "&apikey={key}"
    ).then(function (data) {
        return [data.mus[0].text, data.mus[0].lang]
    })
}

const makeRequest = (art, songs) => {
    songs.forEach((song, i) => {
        delay(3000 * (i+1))
            .then(() => makeSongRequest(art, song.desc))
    })
}

const writeFile = (art, songName, mus) => {
    gen = gens[0]
    let music = {
        artist: art,
        song: {
            name: songName,
            text: mus[0],
            lang: map(mus[1])
        }
    }

    if (fs.existsSync(path.join(__dirname, 'Genders', gen, art))) {
        fs.writeFile(path.join(__dirname, 'Genders', gen, art, `${songName.replace(slash, '')}.json`),
            JSON.stringify(music, null, 4),
            (err) => {
                if (err) throw err
                console.log('Song ' + songName + ' written!')
            })
    } else {
        fs.mkdir(path.join(__dirname, 'Genders', gen, art), { recursive: true }, err => {
            if (err) throw err

            fs.writeFile(path.join(__dirname, 'Genders', gen, art, `${songName.replace(slash, '')}.json`),
                JSON.stringify(music, null, 4),
                (err) => {
                    if (err) throw err
                    console.log('Song ' + songName + ' written!')
                })
        })
    }

}

const makeSongRequest = (art, songName) => {
    requestMusic(art, songName)
        .then(mus => {
            writeFile(art, songName, mus)
        })
}

const delay = t => new Promise (resolve => setTimeout(resolve, t))

const writeSongs = (artist) => {
    art = artist.replace(replacer, '-').toLowerCase()
    return new Promise(() => {
        requestArtSongs(art)
            .then((songs) => {
                makeRequest(artist, songs)
            })
            
    })
}

const main = async () => {
    let gens = ['Funk']
    for (let gen of gens){
        let arts = await fetchArt(gen)
        for (let art of arts) {
            await writeSongs(art)
        }
        
    }
}

main()

在我的主要功能上,我试图从 API 中获取歌词。对于每种性别(在这种情况下,只有“Funk”),我都会找到演唱该性别的艺术家。然后,我为每个艺术家运行 writeSongs 函数,该函数可以做很多事情。我正在使用 Node JS 来完成所有工作。

标签: javascript

解决方案


推荐阅读