Я пытаюсь просмотреть список файлов и в конечном итоге сохранить массив на моем локальном диске. Однако проблема в том, что когда мой код сталкивается с какой-либо ошибкой, он перестает работать и ничего не сохраняет. Я хочу добиться того, чтобы мой цикл продолжал работать даже в случае ошибки.

Я все еще не совсем уверен в использовании Promise,

Я собираюсь получить информацию, используя приведенный ниже код.

function getSongs(id, number) {
    return new Promise((res, rej) => {
        geniusClient.getArtistSongs(id, { "page": `${number}`, "per_page": "50" }, (error, songs) => {
            // console.log(error);
            // console.log(JSON.parse(songs).response.songs);
            if (error) {
                res('error', 'id is: ', id);
            } else {
                let songsArray = JSON.parse(songs)
                // console.log(songsArray.response.songs)
                res(songsArray.response.songs);
            }
        })
    })
}

И сохраните песни, как только я получу их все, как показано ниже.

for (artist of resultArray) {
    console.log(artist.id);
    let songArray = await getSongs(artist.id, 1);
    artist.songs.push(...songArray)
}

// for (artist of resultArray) {
//     console.log(artist.id);
//     let songArray = await getSongs(artist.id, 2);
//     artist.songs.push(...songArray)
// }

roundnumber++;
console.log('round number is', roundnumber);

fs.writeFileSync('./songTest/test.json', JSON.stringify(resultArray))
0
BS100 20 Янв 2021 в 03:13

2 ответа

Лучший ответ

Предлагаемый подход ...

Убедитесь, что getSongs() возвращает отклоненное обещание для максимально возможного количества ошибок.

function getSongs(id, number) {
    return new Promise((res, rej) => {
        // a synchronous error here will result in Promise rejection.
        geniusClient.getArtistSongs(id, { "page": `${number}`, "per_page": "50" }, (error, songs) => {
            try {
                if (error) {
                    throw error; // will be caught below and result in Promise rejection.
                } else {
                    // an (unexpected) error thrown here will also be caught below and result in Promise rejection.
                    let songsArray = JSON.parse(songs);
                    res(songsArray.response.songs);
                }
            } catch(error) {
                rej(error); // reject (expected/unexpected error)
            }
        });
    });
}

В коде вызывающего абонента добавьте структуру try / catch для обработки ошибок.

for (let artist of resultArray) { 
//   ^^^ don't forget to declare variables
    try {
        let songArray = await getSongs(artist.id, 1);
        artist.songs.push(...songArray);
    } catch(error) {
        // catch any error arising from the try block,
        // including any arising from Promise rejection in getSongs().
        artist.songs.push({ 'error': error.message, 'id': artist.id }); // or whatever you want to represent an error
    }
}
2
Roamer-1888 20 Янв 2021 в 02:00

Вы можете использовать Promise.allSettled. . Из документов MDN

Метод Promise.allSettled () возвращает обещание, которое разрешается после того, как все данные обещания были выполнены или отклонены, с массивом объектов, каждый из которых описывает результат каждого обещания.

Храните обещания в массиве, не await их и передавайте этот массив в Promise.allSettled. При этом все ваши ошибки (если они есть) будут сохранены и возвращены вам в массиве в конце операции.

1
Kay 20 Янв 2021 в 00:41