解析,云,工作承诺不起作用

Parse.Cloud.job promise not working

本文关键字:不起作用 承诺 解析 工作      更新时间:2023-09-26

我在这里要做的是:

  1. 首先删除类中的所有内容,因为每天都有事件发生。Json文件将被更新。我有我的第一个问题在这里:有没有一个更好的方法来删除所有的内容从数据库类解析?

  2. 然后我将发送一个请求来获取事件。并将结果的"name"answers"id"存储到一个2D数组中。

  3. 然后我将发送多个请求来获取每个"name"answers"id"对的json文件。

  4. 最后,我将事件细节存储到数据库中。但是现在我的代码将在它下载json文件之前终止。

代码:

function newLst(results) {
  var event = Parse.Object.extend("event");
  for (var i = 0; i < results.length; i++){
    Parse.Cloud.httpRequest({
      url: 'https://api.example.com/events/'+ results[i].name +'/'+ results[i].id +'.json',
      success: function(newLst) {
        var newJson = JSON.parse(newLst.text);
        var newEvent = new event();
        newEvent.set("eventId",newJson.data.id);
        newEvent.set("eventName",newJson.data.title);
        newEvent.save(null, {
          success: function(newEvent) {
            alert('New object created with objectId: ' + newEvent.id);
          },
          error: function(newEvent, error) {
            alert('Failed to create new object, with error code: ' + error.message);
          }
        });
      },
      error: function(newLst) {
      }
    });
  }
};
Parse.Cloud.job("getevent", function(request, status) {
  var event = Parse.Object.extend("event");
  var query = new Parse.Query(event);
  query.notEqualTo("objectId", "lol");
  query.limit(1000);
  query.find({
    success: function(results) {
      for (var i = 0; i < results.length; i++) { 
        var myObject = results[i];
        myObject.destroy({
          success: function(myObject) {
          },
          error: function(myObject, error) {
          }
        });
      }
    },
    error: function(error) {
      alert("Error: " + error.code + " " + error.message);
    }
  });
  var params = { url: 'https://api.example.com/events.json'};
  Parse.Cloud.httpRequest(params).then(function(httpResponse) {
      var results = [];
      var jsonobj = JSON.parse(httpResponse.text);
      for (var i = 0; i < jsonobj.data.length; i++) {
        var tmp2D = {"name":"id"}
        tmp2D.name = [jsonobj.data[i].name];
        tmp2D.id = [jsonobj.data[i].id];
        results.push(tmp2D);
      }
      newLst(results);
  }).then(function() {
      status.success("run job");
  }, function(error) {
      status.error(error);
  });
});

我认为我原来的答案是正确的。这里没有使用额外的代码使其不可读,而是使其非常特定于您的编辑。

关键是消除传递的回调函数。下面的内容都使用了承诺。另一个关键思想是活动分解为逻辑块。

一些注意事项:(1)那里有很多代码,你的代码或我的代码出错的可能性仍然很高,但这应该传达出更好设计的要点。(2)我们在这些函数中做了足够的工作,我们可能会遇到解析强加的超时。从用小计数测试所有这些开始。

从你关于销毁类的所有实例开始

// return a promise to destroy all instances of the "event" class
function destroyEvents() {
    // is your event class really named with lowercase?  uppercase is conventional
    var query = new Parse.Query("event");
    query.notEqualTo("objectId", "lol");  // doing this because the OP code did it.  not sure why
    query.limit(1000);
    return query.find().then(function(results) {
        return Parse.Object.destroyAll(results);
    });
}

接下来,获取远程事件并将其格式化为简单的JSON。请看评论。我很确定你的"二维数组"的想法是不明智的,但我可能误解了你的数据…

// return a promise to fetch remote events and format them as an array of objects
//
// note - this differs from the OP data.  this will evaluate to:
// [ { "name":"someName0", id:"someId0" }, { "name":"someName1", id:"someId1" }, ...]
//
// original code was producing:
// [ { "name":["someName0"], id:["someId0"] }, { "name":["someName1"], id:["someId1"] }, ...]
// 
function fetchRemoteEvents() {
    var params = { url: 'https://api.example.com/events.json'};
    return Parse.Cloud.httpRequest(params).then(function(httpResponse) {
        var results = [];
        var remoteEvents = JSON.parse(httpResponse.text).data;
        for (var i = 0; i < remoteEvents.length; i++) {
            var remoteEvent = { "name": remoteEvents[i].name, "id": remoteEvents[i].id };
            results.push(remoteEvent);
        }
        return results;
    });
}

请仔细检查我所有的工作以上关于格式(例如回应。文本,JSON.parse()。数据,等等)。

当你把回调和承诺混在一起时很容易混淆,当你在循环中生成承诺时更容易混淆。这里,我们再次执行一个简单的操作,根据上面函数中获得的单个远程事件之一创建一个parse.com对象。

// return a promise to create a new native event based on a remoteEvent
function nativeEventFromRemoteEvent(remoteEvent) {
    var url = 'https://api.example.com/events/'+ remoteEvent.name +'/'+ remoteEvent.id +'.json';
    return Parse.Cloud.httpRequest({ url:url }).then(function(response) {
        var eventDetail = JSON.parse(response.text).data;
        var Event = Parse.Object.extend("event");
        var event = new Event();
        event.set("eventId", eventDetail.id);
        event.set("eventName", eventDetail.title);
        return event.save();
    });
}

最后,我们可以将它们整合到一个易于阅读的作业中,确保按照期望的顺序执行操作,并确保在(且仅当)成功完成时调用success()…

// the parse job removes all events, fetches remote data that describe events
// then builds events from those descriptions
Parse.Cloud.job("getevent", function(request, status) {
    destroyEvents().then(function() {
        return fetchRemoteEvents();
    }).then(function(remoteEvents) {
        var newEventPromises = [];
        for (var i = 0; i < remoteEvents.length; i++) {
            var remoteEvent = remoteEvents[i];
            newEventPromises.push(nativeEventFromRemoteEvent(remoteEvent));
        }
        return Parse.Promise.when(newEventPromises);
    }).then(function() {
        status.success("run job");
    }, function(error) {
        status.error(error);
    });
});

发布的代码只做一个http请求,所以不需要一个承诺数组或Promise.when()的调用。通过将httpRequest的回调参数与推送中的承诺和赋值混合在一起,可能发生的其他事情被掩盖了。

这里是一个明确的重写:

Parse.Cloud.job("getevent", function(request, status) {
    var promises = [];
    var params = { url: 'https://api.example.com'};
    Parse.Cloud.httpRequest(params).then(function(httpResponse) {
        var results = [];
        var jsonobj = JSON.parse(httpResponse.text);
        for (var i = 0; i < jsonobj.data.length; i++) {
            // some code
        }
    }).then(function() {
        status.success("run job");
    }, function(error) {
        status.error(error);
    });
});

但是这里有一个非常强烈的警告:只有当("//一些代码")出现在你的原始帖子中,它本身没有尝试做任何异步工作,数据库或其他。

假设你需要在循环中执行异步操作。将这些工作移到一个承诺返回函数中,将它们收集到一个数组中,然后使用Promise.when()。例如…

// return a promise to look up some object, change it and save it...
function findChangeSave(someJSON) {
    var query = new Parse.Query("SomeClass");
    query.equalTo("someAttribute", someJSON.lookupAttribute);
    return query.first().then(function(object) {
        object.set("someOtherAttribute", someJSON.otherAttribute);
        return object.save();
    });
}

然后,在你的循环中…

        var jsonobj = JSON.parse(httpResponse.text);
        var promises = [];
        for (var i = 0; i < jsonobj.data.length; i++) {
            // some code, which is really:
            var someJSON = jsonobj.data[i];
            promises.push(findChangeSave(someJSON));
        }
        return Parse.Promise.when(promises);