Обещание посылает решение до завершения процесса - PullRequest
0 голосов
/ 26 октября 2018

все, У меня есть проект, который спрашивает пользователя, где его целевой URL для загрузки изображений и сжимать их. После того, как я спрашиваю URL пользователя, процесс загружает изображения в каталог один за другим асинхронно, но после загрузки всех файлов я отправляю resolve в этом Обещании. resolve быстрее, чем мой процесс создания файла (загрузки) за миллисекунды. Как я могу отправить resolve после завершения всего процесса загрузки?

const download = (uri, filename, callback) => {
    request.head(uri, (err, res, body) => {
        if(err) return callback(err);
        request(uri).pipe(fs.createWriteStream(filename)).on('close', callback);
    });
};

const downloadImages = (target, inputPath) => {
    return new Promise((resolve, reject) => {
        resource(target)
            .then(res => {
                let count = 0;
                for(let obj in res) {
                    download(res[obj].request.request.url, path.join(path.parse(inputPath).dir, path.parse(url.parse(res[obj].request.request.url).pathname).base), (err) => {
                        if(err) reject(err);
                        console.log(`${path.parse(url.parse(res[obj].request.request.url).pathname).base} file created!`);
                        count++;
                        console.log(count);
                    });
                };
                resolve(true);
            })
            .catch(err => {
                reject(err);
            });
    });
};

const compressImages = (inputPath, outputPath, target) => {
    return new Promise((resolve, reject) => {
        downloadImages(target, inputPath)
            .then(res => {
                if(res === true) {
                    console.log('succeed!');
                };
            })
            .catch(err => {
                reject(err);
            });
    });
};

compressImages('lib/img/*', 'lib/cimg/', 'https://webmedya.com.tr').then(res => {
    if(res === true) console.log('got it!!!')
}).catch(err => {
    console.log(err);
});

И результат этого процесса:

succeed!
got it!!!!!!!!
*after a 10-25 miliseconds*
webmedya-logo.png file created!
1
google-ajansi-ankara.jpg file created!
2
google-ile-zirveye.png file created!
3
adwords-reklam.png file created!
4
youtube-reklam-logo.png file created!
5

Ответы [ 2 ]

0 голосов
/ 26 октября 2018

Можете ли вы попробовать отредактировать цикл for, добавив IIFE и счетчик?Что-то вроде:

for (let obj in res) {
  (function (obj, res) {
    download(..params, (err) => {

    });
  })(res, obj)
};

В идеале рекомендуется не использовать комбинацию обратных вызовов-обещаний.

Если вы планируете использовать только обещания, попробуйте использовать Bluebird , а для обратных вызовов async может помочь!

Надеюсь, это поможет!

0 голосов
/ 26 октября 2018

Поскольку ваша функция download является асинхронным обратным вызовом, resolve не ожидает, пока обратные вызовы не будут вызваны внутри download. Может быть, обернуть download обещанием и вызвать Promise.All созданный массив с помощью цикла for, чтобы добиться цели.

...