Javascript 从循环返回单个resolve()
我编写了以下代码片段:Javascript 从循环返回单个resolve(),javascript,node.js,promise,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 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()
返回了一个承诺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找到文件
未定义
通过请求()下载图像时出错
未处理的拒绝引用错误:未定义拒绝
我的问题是,像和这样的答案都是关于从循环中返回多个承诺。在我的情况下,我只想返回一个承诺解决(取决于匹配),然后停止 我如何做到这一点
谢谢 您不能盲目地在
处理程序中调用resolve()
和reject()
。这些函数仅在手动创建的承诺中定义,因此它们不存在于您的上下文中
如果要在.then()处理程序中设置解析值,则只需返回该值即可。如果要在.then()
处理程序中拒绝,则抛出someErr
或返回被拒绝的承诺
如果您在.forEach()
回调中,并且希望停止进一步处理并设置父承诺的解析值,则无法执行此操作。您位于回调函数内部,因此无法直接从外部函数返回,并且。forEach()
无法停止其迭代。相反,使用常规的for
循环,然后您可以只返回值
,以结束for
循环迭代,并建立承诺链的解析值。常规的for
循环比.forEach()
循环对程序流的控制要多得多
仅供参考,未处理的拒绝引用错误:
是由于试图调用不存在的拒绝()
函数而在.catch()
中创建异常而导致的。去掉那个。如果要记录并拒绝承诺,则抛出
然后,如果在for
循环中使用rp.get()
,则需要将它与wait
或Promise.all()
一起使用,以便知道什么时候一切都完成了。哦,但是我有一个与console.log相对应的.catch()
(“通过请求下载图像时出错”);这与rp.get()
有关,不是吗?还有,你能详细说明一下常规for循环比.forEach()循环对程序流的控制要多得多吗?@J.Doe-是的,我没有看到,因为你的编码风格不同。但是发生此错误是因为您正在使用reject('error in downloading the image via request()')在.catch()
中创建另一个错误代码>之后就没有.catch()
来捕捉新错误了。当然,您不需要另一个.catch()
-只需删除reject.@J.Doe-使用常规的for
循环,您可以返回
或中断
,以停止迭代。使用.forEach()
无法停止迭代。使用.then()
处理程序中的for
循环,您可以使用return someValue
完成.then()
处理程序,设置承诺链的解析值并停止循环。在.forEach()
回调中,您不能执行其中任何一项操作,因为从.forEach()
回调内部返回的操作刚刚完成迭代,.forEach()
循环就一直在进行。@J.Doe-坦白地说,在现代Javascript中使用for/of
和block scope,我很少再使用.forEach()
了。这只是额外的开销和编码的复杂性,没有什么好处。