javascript - 如何为每个用户通过函数进行解析后台作业循环?

标签 javascript parse-platform

我想要做的是让 Parse 后台作业循环遍历数据库中每个 User 的函数,使用该 User 各自的 matchCenterItemMComparisonArray 和其他对象实例作为条件。

当我运行它时,发生的情况是,它没有执行我刚才描述的操作,而是使用 matchCenterItemMComparisonArray 等事物的所有实例运行该函数一次,因此函数无法区分用户。

如何正确地将这个查询中的所有函数关联到每个单独的用户,以便当他们保存新对象时:

var mComparisonArray = Parse.Object.extend("MComparisonArray");
 var newMComparisonArray = new mComparisonArray();
 newMComparisonArray.set('Name', 'MatchCenter');
 newMComparisonArray.set('MCItems', eBayResults);
 newMComparisonArray.set("parent", Parse.User());

它将将该用户显示为父级,而不是在没有父级的情况下保存它。

   Parse.Cloud.job("MatchCenterBackground", function(request, status) {

  console.log('background task started');

  //Query through all users 
  var usersQuery = new Parse.Query(Parse.User);

  //For every user, do the following:
  usersQuery.each(function(user) {
    //query through all their matchCenterItems
    var matchCenterItem = Parse.Object.extend("matchCenterItem");
    var query = new Parse.Query(matchCenterItem);

    // promise and searchterm arrays to be filled
    var promises = [];
    var searchTerms = [];

    //setting the limit of items at 10 for now
    query.limit(10);
    console.log('about to start the matchCenterItem query');

    return query.find().then(function(results) {

      console.log('matchCenterItem query results:' + results);
      if (results.length > 0) {
        console.log('we have entered the matchcenteritem query');

        for (i = 0; i < results.length; i++) {

          console.log('we have also entered the loop inside the matchCenterItem query');
          // later in your loop where you populate promises:
          var searchTerm = results[i].get('searchTerm');
          // add it to the array just like you add the promises:
          searchTerms.push(searchTerm);

          url = 'http://svcs.ebay.com/services/search/FindingService/v1';
          //push function containing criteria for every matchCenterItem into promises array
          promises.push((function() {

            if (results[i].get('itemLocation') == 'US') 
            {
              console.log('americuh!');
              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)': 'New',
                  'itemFilter(0).value(1)': 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': 'US',
                  'itemFilter(4).name=ListingType&itemFilter(4).value': 'FixedPrice',
                  'keywords': results[i].get('searchTerm'),
                }
              });
            } 

            else if (results[i].get('itemLocation') == 'WorldWide') 
            {
              console.log('Mr worlwide!');
              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)': 'New',
                  'itemFilter(0).value(1)': 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' : 'US',
                  'itemFilter(3).name=ListingType&itemFilter(3).value': 'FixedPrice',
                  'keywords': results[i].get('searchTerm'),
                }
              });
            }

            return httpRequestPromise;
          })());
        }
      }

      //when finished pushing all the httpRequest functions into promise array, do the following  
      return Parse.Promise.when(promises).then(function(results) {
        console.log('were in the when.then of promise');

        var eBayResults = [];
        // piece together eBayResults 
        for (var i = 0; i < arguments.length; i++) {
          var httpResponse = arguments[i];
          // since they're in the same order, this is OK:
          var searchTerm = searchTerms[i];
          // pass it as a param:
          var top3 = collectEbayResults(httpResponse.text, searchTerm);
          eBayResults.push(top3);
        }

        // collects ebay responses for every item in the form of top3 
        function collectEbayResults(eBayResponseText, searchTerm) {

          var ebayResponse = JSON.parse(eBayResponseText);
          //console.log('lets check eBayResults here:' + eBayResults);
          var matchCenterItems = [];

          //Parses through ebay's response, pushes each individual item and its properties into an array  
          ebayResponse.findItemsByKeywordsResponse.forEach(function(itemByKeywordsResponse) {
            itemByKeywordsResponse.searchResult.forEach(function(result) {
              result.item.forEach(function(item) {
                matchCenterItems.push(item);
              });
            });
          });

          var top3Titles = [];
          var top3Prices = [];
          var top3ImgURLS = [];
          var top3ItemURLS = [];

          //where the title, price, and img url are sent over to the app
          matchCenterItems.forEach(function(item) {
            var title = item.title[0];
            var price = item.sellingStatus[0].convertedCurrentPrice[0].__value__;
            var imgURL = item.galleryURL[0];
            var itemURL = item.viewItemURL[0];

            top3Titles.push(title);
            top3Prices.push(price);
            top3ImgURLS.push(imgURL);
            top3ItemURLS.push(itemURL);
          });

          console.log('about to define top3 value');
          console.log('btw ebay results is:' + eBayResults);

          var top3 = {
            "Top 3": [{
                "Title": top3Titles[0],
                "Price": top3Prices[0],
                "Image URL": top3ImgURLS[0],
                "Item URL": top3ItemURLS[0]
              },

              {
                "Title": top3Titles[1],
                "Price": top3Prices[1],
                "Image URL": top3ImgURLS[1],
                "Item URL": top3ItemURLS[1]
              },

              {
                "Title": top3Titles[2],
                "Price": top3Prices[2],
                "Image URL": top3ImgURLS[2],
                "Item URL": top3ItemURLS[2]
              },

              {
                "Search Term": searchTerm
              }
            ]
          };
          // return top3
        }


        //After all the above is done, eBayResults has presumably been constructed, and we will now make the comparisons

        //MatchCenter update checking goes here:
        console.log('the eBayResults length is:' + eBayResults.length);
        console.log('the eBayResults are:' + eBayResults);
        // Only check for new matches if user has matchCenterItems  
        if (eBayResults.length > 0) {
          console.log('yes the ebay results be longer than 0');

          //Query users MComparisonArray with the following criteria: 
          var mComparisonArray = Parse.Object.extend("MComparisonArray");
          var mComparisonQuery = new Parse.Query(mComparisonArray);

          mComparisonQuery.contains('Name', 'MatchCenter');
          // mComparisonQuery.contains("MCItems", eBayResults);

          console.log('setup query criteria, about to run it');
          return mComparisonQuery.find().then(function(results) {
            console.log('eh2:' + results);
            // No new items                      
            if (results.length > 0) {
              console.log("No new items, you're good to go!");
            }
            // New items found
            else if (results.length == 0) {

              console.log('no matching mComparisonArray, lets push some new shit');
              //replace MCItems array with contents of eBayResults
              Parse.Object.destroyAll(mComparisonArray);

              var newMComparisonArray = new mComparisonArray();
              newMComparisonArray.set('Name', 'MatchCenter');
              newMComparisonArray.set('MCItems', eBayResults);
              newMComparisonArray.set("parent", Parse.User());

              console.log('yala han save il hagat');
              // Save updated MComparisonArray  
              newMComparisonArray.save().then({
                success: function() {
                  console.log('MComparisonArray successfully created!');
                  //status.success('MComparisonArray successfully created!');
                },
                error: function() {
                  console.log('MComparisonArray error!!!');
                  //status.error('Request failed');
                }
              });
                  //send push notification

            }
              // status.success('MatchCenter Comparison Success!');
          },
            function(err) {
               console.log('nah no results for you bro:' + err); 
            });
        }



      });



    });
  }).then(function() {
    // Set the job's success status
    status.success("background job worked brah!");
  }, function(error) {
    // Set the job's error status
    status.error('DAMN IT MAN');
  });
});

最佳答案

乍一看,我猜这是闭包的问题,​​我发现您已经使用内联函数保护了部分代码,但不是全部。

我建议将您的代码分解为函数并调用它们,这不仅使您的代码更易于阅读和维护,而且还具有保护您免受闭包问题的副作用,例如:

Parse.Cloud.job("MatchCenterBackground", function(request, status) {
    // ... other code to setup usersQuery ...

    usersQuery.each(function (user) {
        return processUser(user);
    }).then(function() {
        status.success("background job worked brah!");
    }, function(error) {
        status.error(error);
    });
});
// process user, return promise
function processUser(user) {
    // ... code to setup per-user query ...

    // easy way to share multiple arrays
    var shared = {
        promises: [],
        searchTerms: [],
    };

    return query.find().then(function(results) {
        // process results, populate shared data (promises and searchTerms)
        buildEbayRequestPromises(results, shared);
    }).then(function() {
        // process promises, return query promise
        return Parse.Promise.when(shared.promises).then(function() {
            // process the results of the promises, returning a query promise
            // ... code here ...
        });
    });
}
// process matchCenterItem results to build eBay promises
function buildEbayRequestPromises(results, shared) {
    // ... code that pushes items into shared.promises and shared.searchTerms ...
}

我没有包含所有级别,但您应该能够从该示例中了解如何更轻松地弄清楚正在发生的事情。

作为一般规则,我喜欢将每个函数保留在不超过一个充满代码的屏幕上,如果超过这个数量,我会尝试将其分解为函数。

关于javascript - 如何为每个用户通过函数进行解析后台作业循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24944054/

相关文章:

javascript - 在 Angular 2 中使用第三方库 (parse.com)

javascript - 自引用 Parse.com 类

javascript - 平滑滚动 div id 到 div id 不起作用?

javascript - 如何开始使用 WebTorrent?

javascript - Aptana Javascript 如何在 aptana 中运行单个 javascript 程序

ios - 解析: fatal error: NSArray element failed to match the Swift Array Element type

javascript - 将 Parse.com JSON 对象放入 Angular $scope 数组中

javascript - 创建独立的离线 HTML5 应用程序以及嵌入其资源的最佳方法

javascript - Vue.js router init 与 router.map 一起使用,而不是与 Router 构造函数一起使用

parse-platform - Firebase AfterSave 功能如 Parse.com