Javascript解析承诺函数给出“未调用成功/错误”错误

Javascript解析承诺函数给出“未调用成功/错误”错误,javascript,promise,Javascript,Promise,我希望我的解析云代码遍历对象的实例,并将每个实例的itemCondition属性记录一次。根据我的研究,因为这是一个异步http请求,所以最好的方法似乎是使用PROMICE语句。然而,当运行下面的尝试时,我得到一个错误,说明错误:未调用success/error。我的印象是,在编写承诺函数时,您不会使用显式的成功/错误语句,对吗 Parse.Cloud.define("MatchCenterTest", function(request, response) { //defines wh

我希望我的解析云代码遍历对象的实例,并将每个实例的itemCondition属性记录一次。根据我的研究,因为这是一个异步http请求,所以最好的方法似乎是使用PROMICE语句。然而,当运行下面的尝试时,我得到一个错误,说明错误:未调用success/error。我的印象是,在编写承诺函数时,您不会使用显式的成功/错误语句,对吗

Parse.Cloud.define("MatchCenterTest", function(request, response) {
    //defines which parse class to iterate through
    var matchCenterItem = Parse.Object.extend("matchCenterItem");
    var query = new Parse.Query(matchCenterItem);
    var promises = [];
    //setting the limit of items at 10 for now
    query.limit(10);
    query.find().then(function(results) {
        //the pinging ebay part
        for (i=0; i<results.length; i++) {
            url = 'http://svcs.ebay.com/services/search/FindingService/v1';
            promises.push(Parse.Cloud.httpRequest({
                url: url,
                params: {
                    'OPERATION-NAME' : 'findItemsByKeywords',
                    'SERVICE-VERSION' : '1.12.0',
                    'SECURITY-APPNAME' : '*APP ID GOES HERE*',
                    'GLOBAL-ID' : 'EBAY-US',
                    'RESPONSE-DATA-FORMAT' : 'JSON',
                    'REST-PAYLOAD&sortOrder' : 'BestMatch',
                    'paginationInput.entriesPerPage' : '3',
                    'outputSelector=AspectHistogram&itemFilter(0).name=Condition&itemFilter(0).value(0)' : results[i].get('itemCondition'),
                    'itemFilter(1).name=MaxPrice&itemFilter(1).value' : results[i].get('maxPrice'),
                    'itemFilter(1).paramName=Currency&itemFilter(1).paramValue' : 'USD',
                    'itemFilter(2).name=MinPrice&itemFilter(2).value' : results[i].get('minPrice'),
                    'itemFilter(2).paramName=Currency&itemFilter(2).paramValue' : 'USD',
                    //'itemFilter(3).name=LocatedIn&itemFilter(3).Value' : request.params.itemLocation,
                    'itemFilter(3).name=ListingType&itemFilter(3).value' : 'FixedPrice',
                    'keywords' : results[i].get('searchTerm'),
                }
            }));
            console.log(results[i].get('itemCondition'));
        }
        Parse.Promise.when(promises).then(function(results) {
            for (i=0; i<results.length; i++)
            {
                var httpresponse = JSON.parse(httpResponse.text);
                response.success(httpresponse);
                console.log(results[i].get('itemCondition'));
            }
        }, function(err) {
            console.log('error!');
        });
    });
});

戈布斯,这里发生了一些事情,让我们一个接一个地看一下:

未调用整个Parse response.success或response.error时,将调用错误error:success/error。这是客户端接收响应所必需的。记住,成功或错误只有一次

对于将函数数组转换为when函数,您的想法是正确的,但我认为您希望执行所有的httpRequest方法,然后从这些方法中获取响应,并在then中处理它们。这里的问题是,您正在执行httpRequest并将响应放在数组上,而实际上您希望数组是一个承诺数组。根据文档,when函数将承诺作为参数或数组,并执行它们。因此,您需要创建一个实际的Parse.Promise对象数组,在撰写本文时,Parse.Cloud.httpRequest返回一个Promise对象。你真走运!因此,您需要做的是将对httpRequest的调用封装在一个函数中,这将产生httpRequest的承诺返回

比如说

    promises.push((function() {
         var httpRequestPromise = Parse.Cloud.httpRequest({
            url: url,
            params: {
                'OPERATION-NAME' : 'findItemsByKeywords',
                'SERVICE-VERSION' : '1.12.0',
                'SECURITY-APPNAME' : '*APP ID GOES HERE*',
                'GLOBAL-ID' : 'EBAY-US',
                'RESPONSE-DATA-FORMAT' : 'JSON',
                'REST-PAYLOAD&sortOrder' : 'BestMatch',
                'paginationInput.entriesPerPage' : '3',
                'outputSelector=AspectHistogram&itemFilter(0).name=Condition&itemFilter(0).value(0)' : results[i].get('itemCondition'),
                'itemFilter(1).name=MaxPrice&itemFilter(1).value' : results[i].get('maxPrice'),
                'itemFilter(1).paramName=Currency&itemFilter(1).paramValue' : 'USD',
                'itemFilter(2).name=MinPrice&itemFilter(2).value' : results[i].get('minPrice'),
                'itemFilter(2).paramName=Currency&itemFilter(2).paramValue' : 'USD',
                //'itemFilter(3).name=LocatedIn&itemFilter(3).Value' : request.params.itemLocation,
                'itemFilter(3).name=ListingType&itemFilter(3).value' : 'FixedPrice',
                'keywords' : results[i].get('searchTerm'),
            }
        })
      return httpRequestPromise;
    })());
最后,您如何处理响应。在这里可以找到then的API文档,它说then将为您提供一个函数,该函数将所有承诺响应作为参数。但是,由于您处于循环中,并且不知道每个调用有多少个参数,因此您可以只使用通用参数reserved var。例如,假设您希望从请求中收集响应:

Parse.Promise.when(promises).then(function() {
    var allResponses = []
    for (i=0; i<arguments.length; i++)
    {
        var httpResponse = arguments[i];
        var responseObj = JSON.parse(httpResponse.text);
        allResponses.push(responseObj);
    }
    // and by the way if this is the end of your function, then here you can call
    response.success(allResponses);
}, function(err) {
    console.log('error!');
    response.error();
});

希望这有帮助,祝你好运

Ghobs,这里发生了一些事情,让我们一个接一个地看一下:

未调用整个Parse response.success或response.error时,将调用错误error:success/error。这是客户端接收响应所必需的。记住,成功或错误只有一次

对于将函数数组转换为when函数,您的想法是正确的,但我认为您希望执行所有的httpRequest方法,然后从这些方法中获取响应,并在then中处理它们。这里的问题是,您正在执行httpRequest并将响应放在数组上,而实际上您希望数组是一个承诺数组。根据文档,when函数将承诺作为参数或数组,并执行它们。因此,您需要创建一个实际的Parse.Promise对象数组,在撰写本文时,Parse.Cloud.httpRequest返回一个Promise对象。你真走运!因此,您需要做的是将对httpRequest的调用封装在一个函数中,这将产生httpRequest的承诺返回

比如说

    promises.push((function() {
         var httpRequestPromise = Parse.Cloud.httpRequest({
            url: url,
            params: {
                'OPERATION-NAME' : 'findItemsByKeywords',
                'SERVICE-VERSION' : '1.12.0',
                'SECURITY-APPNAME' : '*APP ID GOES HERE*',
                'GLOBAL-ID' : 'EBAY-US',
                'RESPONSE-DATA-FORMAT' : 'JSON',
                'REST-PAYLOAD&sortOrder' : 'BestMatch',
                'paginationInput.entriesPerPage' : '3',
                'outputSelector=AspectHistogram&itemFilter(0).name=Condition&itemFilter(0).value(0)' : results[i].get('itemCondition'),
                'itemFilter(1).name=MaxPrice&itemFilter(1).value' : results[i].get('maxPrice'),
                'itemFilter(1).paramName=Currency&itemFilter(1).paramValue' : 'USD',
                'itemFilter(2).name=MinPrice&itemFilter(2).value' : results[i].get('minPrice'),
                'itemFilter(2).paramName=Currency&itemFilter(2).paramValue' : 'USD',
                //'itemFilter(3).name=LocatedIn&itemFilter(3).Value' : request.params.itemLocation,
                'itemFilter(3).name=ListingType&itemFilter(3).value' : 'FixedPrice',
                'keywords' : results[i].get('searchTerm'),
            }
        })
      return httpRequestPromise;
    })());
最后,您如何处理响应。在这里可以找到then的API文档,它说then将为您提供一个函数,该函数将所有承诺响应作为参数。但是,由于您处于循环中,并且不知道每个调用有多少个参数,因此您可以只使用通用参数reserved var。例如,假设您希望从请求中收集响应:

Parse.Promise.when(promises).then(function() {
    var allResponses = []
    for (i=0; i<arguments.length; i++)
    {
        var httpResponse = arguments[i];
        var responseObj = JSON.parse(httpResponse.text);
        allResponses.push(responseObj);
    }
    // and by the way if this is the end of your function, then here you can call
    response.success(allResponses);
}, function(err) {
    console.log('error!');
    response.error();
});

希望这有帮助,祝你好运

Ghobs我通过IDE运行了你的代码,并删除了参数{}后的一个多余的尾随逗号,不确定它是否影响了你的代码,但iirc它会阻塞IE8。谢谢你捕捉到这一点!但我在修复后仍然会遇到同样的错误。戈布斯,我认为这是一个承诺?承诺一旦解决,就不能再解决。因此,您可能需要放置该响应;在循环之外。我没有访问此API的权限,但如果您可以构建一个我可以使用的小提琴,我将帮助您完成此任务。是否有用于解析的CDN,您需要帐户吗?@Shanimal我明白您的意思。我尝试将响应调用置于循环之外,导致应用程序崩溃。不幸的是,您无法通过fiddle运行它,因为您需要访问我的解析数据库。Ghobs我通过IDE运行了您的代码,并删除了params:{}后面的一个多余的尾随逗号,不确定它是否影响了您的代码,但iirc它会阻塞IE8。感谢您捕捉到这一点!但我在修复后仍然会遇到同样的错误。戈布斯,我认为这是一个承诺?承诺一旦解决,就不能再解决。因此,您可能需要放置该响应;o
环的外侧。我没有访问此API的权限,但如果您可以构建一个我可以使用的小提琴,我将帮助您完成此任务。是否有用于解析的CDN,您需要帐户吗?@Shanimal我明白您的意思。我尝试将响应调用置于循环之外,导致应用程序崩溃。不幸的是,您不能通过fiddle运行它,因为您需要访问我的解析数据库。