Дождитесь, пока узел закончит запись файла с https.получите ответ, прежде чем продолжить?

#javascript #node.js

Вопрос:

Циклы while создают кошельки ethereum, загружают аватары robohash в соответствии с сгенерированными адресами и записывают их в файл. gLoops устанавливает количество созданных кошельков. Мне нужно, чтобы отрывок подождал, пока файл аватара загрузится и будет записан в файл, прежде чем продолжить цикл while. Я считаю, что это должно быть сделано с асинхронностью/ожиданием, но не могу понять этого

 let gLoops = 0;
while (gLoops < 10) {

pKey = crypto.randomBytes(32).toString("hex");
wallet = new ethers.Wallet(pKey);
address = wallet.address;

let url = urlBase   address;

https.get(url, (response) => {
    let filePath = `${arg1path}\avatars\${address}.jpg`;
    let stream = fs.createWriteStream(filePath);

    response.pipe(stream);
    stream.on("finish", () => {
        stream.close();
        console.log("Download Completed");
    });
});

gLoops  ;
}
 

Ответ №1:

Вы можете завернуть свое https.get() обещание в обещание и использовать await его для for приостановки цикла для его завершения:

 function processAvatar(pKey, wallet, address, url) {
    return new Promise((resolve, reject) => {
        https.get(url, (response) => {
            let filePath = `${arg1path}\avatars\${address}.jpg`;
            let stream = fs.createWriteStream(filePath);

            response.on("error", reject);

            stream.on("finish", () => {
                stream.close();
                console.log("Download Completed");
                resolve();
            }).on("error", reject);

            response.pipe(stream);

        }).on("error", reject);
    });
}


async function run() {
    for (let gLoops = 0; gLoops < 10;   gLoops)
        let pKey = crypto.randomBytes(32).toString("hex");
        let wallet = new ethers.Wallet(pKey);
        let address = wallet.address;
        let url = urlBase   address;
        await processAvatar(pKey, wallet, address, url);
    }    
}

run().then(() => {
    console.log("all done");
}).catch(err => {
    console.log(err);
});
 

Кроме того, вы можете использовать одну из библиотек http-запросов, упомянутых здесь, которые уже знают об обещаниях, и использовать их напрямую. Моим любимым в этом списке является got() библиотека, и она поддерживает потоки так, как вы ее используете.

Комментарии:

1. Большое спасибо, это как раз то, что мне было нужно. Я рассмотрю обещания. p.s. Я думаю, что C/C был бы лучшим выбором для задач синхронизации, подобных этой

2. @bitbar — Я не знаю особой причины, по которой C/C был бы лучше в этом, чем nodejs. Вам просто нужно узнать, как обещания работают в nodejs, и использовать библиотеку http, которая их поддерживает. В наши дни это требуется для большинства программ в nodejs, поэтому просто необходимо научиться эффективно использовать среду программирования nodejs.

Ответ №2:

Попробуйте использовать функцию асинхронного ожидания для своих функций?