【问题标题】:Promise sends resolve before the process finishPromise 在流程完成之前发送解决方案
【发布时间】:2019-03-31 01:16:22
【问题描述】:

大家, 我有一个项目,它询问用户他们的目标 URL 以下载图像并压缩它们。在我询问用户 URL 之后,该过程将图像一个一个异步地下载到一个目录中,但是,在所有文件下载之后,我在这个 Promise 中发送resolveresolve 比我创建文件(下载)过程快几毫秒。整个下载过程结束后如何发送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

【问题讨论】:

  • 你在哪里打电话解决?在您的代码中找不到
  • 哦,哇!太抱歉了,我在for...in循环之后添加了,谢谢!

标签: node.js asynchronous download promise request


【解决方案1】:

由于您的download 函数是一个异步回调,resolve 不会等到在download 内部调用回调。也许用 promise 包装 download 并通过 for 循环调用 Promise.All 制作的数组就可以了。

【讨论】:

  • 如何用Promise.all()函数改变for...in函数?你能帮我解决一下吗?
  • 什么是请求模块?
  • 它只是在这个项目中向流管道发出请求。
  • 它可以返回一个承诺吗?
  • 太棒了。没问题
【解决方案2】:

您能否尝试通过添加 IIFE 和计数器来编辑您的 for 循环?比如:

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

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

理想情况下,建议您不要使用回调-承诺的组合。

如果您打算只使用 Promise,请尝试使用 Bluebird,对于回调 async 可能会有所帮助!

希望这会有所帮助!

【讨论】:

  • counter怎么样?我只做了这个:for(let obj in res) { ((obj, res) => { download(res[obj].request.request.url, filename) .then(() => { console.log(${filename} created!); count++; console.log(count); }) .catch(err => { reject(err); }); })(obj, res); };
  • 嗨 @n3pixowe,添加 IIFE 将帮助您的方法在执行时保持状态。因此,要运行它,您需要使用计数器来跟踪,在您的“下载”回调中添加:count++; if (Object.keys(res).length === count) { return resolve(true); }
  • 你刚刚损坏了我的大脑!谢谢老哥的解决方案!你很好:)
  • 当然,很高兴为您提供帮助!
猜你喜欢
  • 2018-04-28
  • 2020-02-19
  • 1970-01-01
  • 1970-01-01
  • 2020-12-27
  • 1970-01-01
  • 2018-07-07
  • 2019-02-27
  • 1970-01-01
相关资源
最近更新 更多