从循环返回单个resolve()

时间:2019-08-14 03:33:31

标签: javascript node.js promise

我写了下面的代码片段:

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())导入的函数readFile.js返回了诺言。 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文件读取一个文件(将标题映射到URL),然后将图像下载到相应的URL。一旦找到此匹配项(如果有上述if子句),则应解决诺言并将其返回到新模块。

现在发生的是,我得到以下输出:

  

node ./lib/getImage.js -n title -t topText -b bottomText
  找到文件
  未定义
  <... image ...作为base64字符串>
  通过request()下载图像时出错
  未处理的拒绝ReferenceError:未定义拒绝...

我的问题是,thisthis之类的答案都谈到从循环中返回多个promise。就我而言,我只想返回一个promise resolve(取决于匹配)并停止。

我该如何实现?

谢谢!

1 个答案:

答案 0 :(得分:0)

您不只是在resolve()处理程序中盲目调用reject().then()。这些功能仅在手动创建的Promise中定义,因此在您的上下文中不存在。

如果要在.then()处理程序中设置解析的值,则只需return即可。如果您想在.then()处理程序内拒绝,则throw someErrreturn会拒绝一个诺言。

如果您在.forEach()回调中,并且想要停止进一步的处理并设置父承诺的已解析值,则不能。您位于回调函数内部,因此无法直接从外部函数return进行操作,.forEach()无法停止其迭代。相反,使用常规的for循环,然后您可以return value结束for循环迭代并建立您的Promise链的解析值。与for循环相比,常规的.forEach()循环为您提供了对程序流的更多控制。

仅供参考,Unhandled rejection ReferenceError:是通过尝试调用不存在的.catch()函数在reject()内部创建异常而引起的。删除它。如果要记录并拒绝兑现承诺,请throw

然后,如果您在rp.get()循环中使用for,则需要将其与awaitPromise.all()一起使用,以便知道何时一切完成。

相关问题