javascript 从循环中返回单个resolve()

w46czmvw  于 2023-04-10  发布在  Java
关注(0)|答案(1)|浏览(211)

我写了下面的代码片段:

var data = require('./readFile.js');
const argv = require('./index.js');
const colors = require('colors');
const rp = require('request-promise').defaults({ encoding: null });
const memeImage = argv.name;
const path = './json/meme.json';

var myData;

data.readFile(path)
.then(function (value) {
    var jsonData = JSON.parse(value);

    const options = {
        resolveWithFullResponse: true
    }
    jsonData.forEach(element => {
        if(element.title == memeImage) {
            rp.get(element.image, options)
            .then(function(response){
                if(response.statusCode == 200) {
                    myData = Buffer.from(response.body).toString('base64');
                    myData.replace('myData:image/png;base64,', '');
                    console.log(myData);

                    resolve(myData);
                }
                else {
                    console.log('Error in retrieving image.  Status code: ', response.statusCode);
                    reject('Error in retrieving image.');
                }
            })
            .catch(function(error){
                console.log('Error in downloading the image via request()');
                reject('Error in downloading the image via request()');
            });
        }
    });
})
.then(function(myData) {
    console.log(myData);
})
.catch(function(err) {
    //Error in reading the file
    console.log(err);
})

module.exports=myData;

这里,从另一个文件(readFile.js)导入的函数readFile()返回了一个promise。readFile.js如下:

var myData, obj, found=false;

function readFile(path) {
    return new Promise(function(resolve, reject){
        if(!fs.existsSync(path)) {
            console.log('Will throw error now!');
            reject("memes.json file does not exist");
        }
        else {
            //File exists
            console.log('File found');
            var data = fs.readFileSync(path, 'utf8');
            resolve(data);
        }
    })
}

module.exports.readFile = readFile;

现在在最上面的代码片段中,我的目标是使用readFile.js文件读取一个文件(将标题Map到URL),然后在相应的URL处下载图像。一旦找到这个匹配(上面的if子句),promise应该被解析并返回到一个新的模块。
现在发生的是,我得到以下输出:
node ./lib/getImage.js -n title -t topText -b bottomText
找到的文件
未定义的
〈... image ... as a base64 string〉
通过request()下载镜像时出错
未处理的拒绝引用错误:reject未定义...
我的问题是,像thisthis这样的答案都在谈论从一个循环中返回多个promise。在我的例子中,我只想返回一个promise resolve(取决于匹配),然后停止。
我如何实现这一点?

q5iwbnjs

q5iwbnjs1#

你不能在.then()处理程序中盲目地调用resolve()reject()。这些函数只在手动创建的promise中定义,所以它们不存在于你的上下文中。
如果你想在.then()处理程序中设置resolved值,那么只需return该值。如果你想在.then()处理程序中拒绝,那么throw someErrreturn是一个被拒绝的promise。
如果你在一个.forEach()回调函数中,你想停止进一步的处理,并设置父promise的resolved值,你不能。你在一个回调函数中,所以你不能直接从外部函数return.forEach()没有办法停止它的迭代。相反,使用一个常规的for循环,然后你可以只使用return value来结束for循环迭代,并建立你的promise链的解析值。常规的for循环比.forEach()循环能让您对程序流有更多的控制。
仅供参考,Unhandled rejection ReferenceError:是由于试图调用不存在的reject()函数而在.catch()内部创建异常引起的。请删除该异常。如果您想记录并保留拒绝的承诺,请使用throw
然后,如果在for循环中使用rp.get(),则需要将其与awaitPromise.all()一起使用,以便知道何时完成所有操作。

相关问题