Javascript JSON解析承诺无法正常运行

Javascript JSON解析承诺无法正常运行,javascript,json,parsing,typescript,Javascript,Json,Parsing,Typescript,我正在创建一个Promise,它应该添加在array/JSON对象中找到的任何数字 add()应该接收一个URL字符串,并输出这些URL的总和 我的做法如下: 我创建了一个名为parse的助手函数,它接收一个字符串(url),并输出位于url的JSON对象 我的问题是,在$$$表示的区域,objectjsonObject是正确解析的JSON对象。但是,在****表示的区域,在我调用parse之后,parsedObj不再是正确解析的JSON对象 例如,如果我解析一个包含[1,2,5,4]的JSON

我正在创建一个Promise,它应该添加在array/JSON对象中找到的任何数字

add()应该接收一个URL字符串,并输出这些URL的总和

我的做法如下:

我创建了一个名为parse的助手函数,它接收一个字符串(url),并输出位于url的JSON对象

我的问题是,在$$$表示的区域,object
jsonObject
是正确解析的JSON对象。但是,在****表示的区域,在我调用parse之后,
parsedObj
不再是正确解析的JSON对象

例如,如果我解析一个包含
[1,2,5,4]
的JSON对象,我将得到
jsonObject=1,2,5,4
,但是
parsedObj=[object Promise]

为什么
parsedObj
是[objectpromise]的数组而不是
1,2,5,4

parse(url:string):any
返回一个承诺,而不是您的jsonObject

所以

实际上是异步的。 您将使用

parsedObj.then(function(jsobObject){
                for (var elmt of jsobObject) {
                    if (elmt.isNumber()) {
                        sum += elmt;
                        countNums++;
                    }
                    Log.trace("sum: " + sum);
                }

                Log.trace("sum: " + sum);
})

您需要将parsedObj(您的承诺)存储在一个数组中,以使用另一个Promise.all()来在所有工作完成后履行您的父承诺

我猜您的假设是,
parse()
将返回已解决的问题,因为代码中有一个
Promise.all()

由于您的代码过于复杂,并且您正在使用延迟反模式,因此我已经清理了您的代码

parse(url: string): any {
    let rp = require('request-promise-native');
    return rp({ uri: url })
        .then(
            JSON.parse, 
            function(err){ 
                throw "Error: URL could not be retrieved" 
            }
        );
}


add(urls: string[]): Promise<number> {
    return Promise.all(urls.map(this.parse))
        .then(function(arrays) {
            let emptyArray = [];
             //flatten
            let numbers = emptyArray.concat.apply(emptyArray, arrays)
                //remove non-numeric entries
                .filter(function(v){
                    return v.isNumber();
                });

            if(0 === numbers.length){
                throw "Error: No number was provided";
            }

            //sum
            return numbers.reduce(function(a,b){ 
                return a+b;
            });
        });
}
parse(url:string):任意{
设rp=require('request-promise-native');
返回rp({uri:url})
.那么(
JSON.parse,
函数(err){
抛出“错误:无法检索URL”
}
);
}
添加(URL:string[]):承诺{
返回Promise.all(url.map(this.parse))
.then(函数(数组){
让emptyArray=[];
//压扁
让number=emptyArray.concat.apply(emptyArray,数组)
//删除非数字项
.过滤器(功能(v){
返回v.isNumber();
});
if(0==numbers.length){
抛出“错误:未提供编号”;
}
//总数
返回数.reduce(函数(a,b){
返回a+b;
});
});
}
不过,我把日志漏掉了


有什么问题吗?

你能提供一把小提琴吗?@Harper04抱歉,那是什么?你能在$$$部分记录
url
参数吗?您确定返回的元素是字符串吗?您好@briosheje,谢谢您的回复。我已经这样做了,
url
是一个字符串。@chisquare提供了一个工作示例代码,演示了您在可运行环境中的问题,其中有一些平台。帮助我们直接使用您的代码。非常感谢您为此所做的努力。我现在明白我错在哪里了。不过最后一件事是,它抱怨
jsobObject
属于任何类型。你知道最好的补救办法是什么吗?我对JSON不太熟悉。看起来您使用的是typescript,它是javascript的超集。只需查看typescript文档即可设置哪种类型。like函数(jsonObject:object)(如果存在类似对象的东西…)正确。再次感谢。祝你度过愉快的一天。如果你不介意的话,请再跟进一次。由于某种原因,总和永远不会正确计算。相反,会发生失败,返回错误,表示未提供任何号码。我怀疑这是因为带有fully()的if语句是在then()之前执行的?有没有关于我如何解决这个问题的建议?请看@Thomas answer。我只回答了您的问题,并指出您应该重新访问您的控制流。他在上面做了所有的清理工作——你真的应该用他的方式来写这篇文章。在Promise.all(url.map(this.parse))中使用map真的很酷,而且比嵌套Promise.all()要好得多
parse(url: string): any {
    let rp = require('request-promise-native');
    return rp({ uri: url })
        .then(
            JSON.parse, 
            function(err){ 
                throw "Error: URL could not be retrieved" 
            }
        );
}


add(urls: string[]): Promise<number> {
    return Promise.all(urls.map(this.parse))
        .then(function(arrays) {
            let emptyArray = [];
             //flatten
            let numbers = emptyArray.concat.apply(emptyArray, arrays)
                //remove non-numeric entries
                .filter(function(v){
                    return v.isNumber();
                });

            if(0 === numbers.length){
                throw "Error: No number was provided";
            }

            //sum
            return numbers.reduce(function(a,b){ 
                return a+b;
            });
        });
}