Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从循环返回单个resolve()_Javascript_Node.js_Promise - Fatal编程技术网

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()
了。这只是额外的开销和编码的复杂性,没有什么好处。