我写了下面的代码片段:
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:未定义拒绝...
我的问题是,this和this之类的答案都谈到从循环中返回多个promise。就我而言,我只想返回一个promise resolve(取决于匹配)并停止。
我该如何实现?
谢谢!
答案 0 :(得分:0)
您不只是在resolve()
处理程序中盲目调用reject()
和.then()
。这些功能仅在手动创建的Promise中定义,因此在您的上下文中不存在。
如果要在.then()
处理程序中设置解析的值,则只需return
即可。如果您想在.then()
处理程序内拒绝,则throw someErr
或return
会拒绝一个诺言。
如果您在.forEach()
回调中,并且想要停止进一步的处理并设置父承诺的已解析值,则不能。您位于回调函数内部,因此无法直接从外部函数return
进行操作,.forEach()
无法停止其迭代。相反,使用常规的for
循环,然后您可以return value
结束for
循环迭代并建立您的Promise链的解析值。与for
循环相比,常规的.forEach()
循环为您提供了对程序流的更多控制。
仅供参考,Unhandled rejection ReferenceError:
是通过尝试调用不存在的.catch()
函数在reject()
内部创建异常而引起的。删除它。如果要记录并拒绝兑现承诺,请throw
。
然后,如果您在rp.get()
循环中使用for
,则需要将其与await
或Promise.all()
一起使用,以便知道何时一切完成。