我写了下面的代码片段:
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未定义...
我的问题是,像this和this这样的答案都在谈论从一个循环中返回多个promise。在我的例子中,我只想返回一个promise resolve(取决于匹配),然后停止。
我如何实现这一点?
1条答案
按热度按时间q5iwbnjs1#
你不能在
.then()
处理程序中盲目地调用resolve()
和reject()
。这些函数只在手动创建的promise中定义,所以它们不存在于你的上下文中。如果你想在
.then()
处理程序中设置resolved值,那么只需return
该值。如果你想在.then()
处理程序中拒绝,那么throw someErr
或return
是一个被拒绝的promise。如果你在一个
.forEach()
回调函数中,你想停止进一步的处理,并设置父promise的resolved值,你不能。你在一个回调函数中,所以你不能直接从外部函数return
,.forEach()
没有办法停止它的迭代。相反,使用一个常规的for
循环,然后你可以只使用return value
来结束for
循环迭代,并建立你的promise链的解析值。常规的for
循环比.forEach()
循环能让您对程序流有更多的控制。仅供参考,
Unhandled rejection ReferenceError:
是由于试图调用不存在的reject()
函数而在.catch()
内部创建异常引起的。请删除该异常。如果您想记录并保留拒绝的承诺,请使用throw
。然后,如果在
for
循环中使用rp.get()
,则需要将其与await
或Promise.all()
一起使用,以便知道何时完成所有操作。