Nodejs запускает функцию до завершения предыдущей функции - PullRequest
1 голос
/ 26 февраля 2020

Что мне нужно сделать, это

  1. , чтобы проверить, существует ли fileFullPath, существует
  2. , если нет, в конце успешной загрузки файла позвонить saveInfo.

Когда я выполняю приложение, я вижу, что перед завершением операции записи в файл оно вызывает saveInfo. И я получаю сообщение об ошибке:

(node:20224) UnhandledPromiseRejectionWarning: Error: BatchCluster has ended, cannot enqueue -charset

Что я делаю не так?

async function dl(url, path, data = null) {

    await request.get({
        url: url,
    })
        .on("error", async function (error) {
            console.log(error);
            return false;
        })
        .on('response', async function (res) {
            var fileExt = res.headers['content-type'].split('/')[1];
            var fileFullPath = `${path}.${fileExt}`;
            await res.pipe(fs.createWriteStream(fileFullPath));
            console.log("file downloaded");
            if (data) {
                await saveInfo(fileFullPath, data);
            }
        });
    return true;

}

async function saveInfo(filePath, data) {
    await exiftool.write(filePath, {
        Keywords: data.keywords,
        Copyright: data.copyright,
    });
    console.log("Tags are saved");
    exiftool.end();
}

1 Ответ

0 голосов
/ 26 февраля 2020

ОК, я нашел способ сделать это. Трубопровод к потокам не очень дружелюбен к обещаниям, поэтому я в итоге сделал некоторые ручные манипуляции с обещаниями. Я думаю, что обещание поддержки потоков будет достигать node.js, поскольку у нас уже есть несколько асинхронных c итераторов. В любом случае, вот способ заставить все работать, наблюдая за правильными событиями в ваших потоках:

function dl(url, path, data = null) {

    return new Promise((resolve, reject) => {
        request.get({
            url: url,
        }).on("error", function (error) {
                console.log(error);
                reject(error);
        }).on('response', function (res) {
            let fileExt = res.headers['content-type'].split('/')[1];
            let fileFullPath = `${path}.${fileExt}`;
            let writeStream = fs.createWriteStream(fileFullPath);

            // set up event handlers to monitor the writeStream for error or completion
            writeStream.on('error', reject).on('close', async () => {
                if (data) {
                    try {
                        await saveInfo(fileFullPath, data);
                    } catch(e) {
                        reject(e);
                        return;
                    }
                }
                console.log("file downloaded");
                resolve(true);
            });

            // send the response stream to our file
            res.pipe(writeStream).on('error', reject);
        });
    });
}

async function saveInfo(filePath, data) {
    await exiftool.write(filePath, {
        Keywords: data.keywords,
        Copyright: data.copyright,
    });
    console.log("Tags are saved");
    exiftool.end();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...