如何在Parse Cloud Code中链接函数?

时间:2015-04-21 11:57:37

标签: javascript parse-platform cloud-code

我已经做了一个解析工作,如果“emailSent”为false,则为每个用户检查每个“X”时间。如果是,我调用函数发送电子邮件并将“emailSent”更改为true。这样可行。 我的问题是函数“getMaxId”。我需要返回maxid值来更改每个用户“id_client”列,但我不知道如何。我试过这个,但它不起作用。这没有写任何东西:“console.log(”Write somethingggg“);”

这是代码......

Parse.Cloud.job("test", function(request, status) {
  // Set up to modify user data
  Parse.Cloud.useMasterKey();

  var texto = "New verified emails:\n\t";
  // Query for all users
  var query = new Parse.Query(Parse.User);
  //query.equalTo("emailVerified", true);
  query.equalTo("emailSent", false);
  query.each(function(user) {

  user.set("emailSent", true);
user.save(); 
var datos = user.get("email")+"\n";
texto=texto+datos;

Parse.Cloud.run("getMaxId", {},{
success: function(results) {
console.log("Write somethingggg"); 
    user.set("id_client", "gofoadasda");
    user.save();
    var datos = user.get("id_client")+"\n";
    //console.log("id_client: "+datos);
    response.success();


},
error: function(results, error) {
  response.error(errorMessageMaker("running chained function",error));
}

  }).then(function() {

// Set the job's success status


  }, function(error) {
    // Set the job's error status
    status.error("Uh oh, something went wrong.");

});
    Parse.Cloud.run("sendEmail",{
    success: function(results) {

        response.success(results);

    },
error: function(results, error) {
  response.error(errorMessageMaker("running chained function",error));
}

  });

  }).then(function() {

    // Set the job's success status
    console.log("texto: "+texto);
    status.success("Migration completed successfully.");
   }, function(error) {
      // Set the job's error status
      status.error("Uh oh, something went wrong.");
    });
  });
  Parse.Cloud.define("sendEmail", function(request, response) {
      Parse.Cloud.httpRequest({
            url: 'http://www.example.com/sendemail.php',
            params: {
        email : 'email@email.com'
        },
        success: function(httpResponse) {
        console.log(httpResponse.text);
        },
        error: function(httpResponse) {
    console.error('Request failed with response code ' + httpResponse.status);
}
});
  });

  Parse.Cloud.define("getMaxId", function(request,response) {
      var query = new Parse.Query(Parse.User); 
      query.descending("id_client");  
      query.find({
          success: function(results) {
        var idmax=results[0].get("id_client")
        console.log("idmax: "+idmax);
        response.success(idmax);

    },
    error: function() {
        response.error(" is an error");
    }
      });

  });

第一次更改:

在@danh帮助之后,我尝试做我需要的,改变一些代码:

重要提示:id_client是一个int值,它对每个用户都是唯一的,它从20000开始。

  1. 获取标志为sentEmail = false的所有用户。
  2. 对于每个用户,getMaxId(这将返回所有用户的实际最大“id_client”值。)
  3. 将sentEmail的值更改为true,将用户id_client设置为实际的最大ID。
  4. 发送电子邮件。
  5. 新代码(sendEmail没有变化):

    var _ = require('underscore');
    
    // return a promise to get the max value of id_client in the user table
    function getMaxId(user) {
        var query = new Parse.Query(Parse.User); 
        //return query.count();
        query.descending("id_client");
        query.limit(1);
        return query.find().then(function(users) {
            if(users[0].get("id_client")<20000){ //No users yet.
                user.set("id_client", 20000);  //First id:20000
                user.save();
                return 20000;
            }
            else{ //There are users. Get the maxId and increment +1.
                user.set("id_client", users[0].get("id_client")+1);
                user.save();
                return (users.length)? users[0].get("id_client")+1 : 0;
            }
        });
    }
    // return a promise for users with emailSent flag == false
    function usersWithUnsentEmail() {
        var query = new Parse.Query(Parse.User);
        query.equalTo("emailSent", false);
        return query.find();
    }
    // return a promise to send email to the given user, and to set its 
     // emailSent flag = true
     function sendEmailToUser(user) {
         return sendEmail(user.get("email")).then(function() {
             user.set("emailSent", true);
             return user.save();
         });
     }
    Parse.Cloud.job("test", function(request, response) {
    // Set up to modify user data
    Parse.Cloud.useMasterKey();
    
    usersWithUnsentEmail().then(function (users){
        var emailPromises = _.map(users, function(user) {
            //what I understand is that here, for each user, we call getMaxId, getting the actual max id_client, and then, we pass it to "sendEmailToUser".
            return getMaxId(user).then(function(max){
                return sendEmailToUser(user);
            });
        });
        return Parse.Promise.when(emailPromises);//This means that we have looped all users, is it?
    }).then(function(results) {
        response.success(results);
    }, function(error) {
        response.error(error);
    });
    });
    

    我用2个用户测试了这个,标志为“sentEmail”= false,实际最大id_client为20001 结果:

    1. sentEmail标记已正确更改。
    2. 正确发送了2封电子邮件。
    3. 错误:两个用户的id_client都更改为20002.它必须是20002和20003。
    4. 登录解析:

      I2015-04-22T09:44:13.433Z] v90: Ran job test with:
        Input: {}
        Result: undefined
      E2015-04-22T09:44:29.005Z] v90: Ran job test with:
        Input: {}
        Failed with: Error: Job status message must be a string
          at updateJobMessageAndReturn (<anonymous>:790:7)
          at Object.success (<anonymous>:828:9)
          at main.js:217:18
          at e (Parse.js:3:8736)
          at Parse.js:3:8185
          at Array.forEach (native)
          at Object.x.each.x.forEach [as _arrayEach] (Parse.js:1:661)
          at c.extend.resolve (Parse.js:3:8136)
          at Parse.js:3:8815
          at e (Parse.js:3:8736)
      

      编辑:

      我们需要他们的电子邮件和我们将分配的id_client。

      可能我没有解释清楚,电子邮件不会发送到用户的电子邮件,电子邮件将发送到我在sendemail.php脚本中确定的电子邮件,它将始终是相同。

      我将解释:你家里有一个本地数据库,并解析数据库。当调用此Parse.job时,它会向您发送一封电子邮件(php的电子邮件),其中包含电子邮件列表和每个用户的id_client已更新。现在,您可以使用收到的电子邮件信息手动更新本地数据库。

      因此,在所有更新结束时,最好只发送一封电子邮件。 (我没有这么说,因为我在尝试理解cloudCode如何工作时遇到了很多问题......)

1 个答案:

答案 0 :(得分:0)

在代码中有一些需要修复的东西:(1)作为一项规则,使用promises 如果你做两件以上的连续异步事情,(2) don从云代码中调用Parse.Cloud.run ,这是你从希望调用云功能的客户那里调用的,(3)风格方面,你会疯狂地试图在以后找到它,除非你将代码分解为小的,承诺返回的步骤

我已将所有三点建议应用于您的代码。我不完全理解代码和文本中描述的逻辑,但希望我足够接近你理解它。

// using underscore js, which provides _.map below as well as loads of other useful stuff
var _ = require('underscore');

// return a promise to get the max value of id_client in the user table
function getMaxId() {
    var query = new Parse.Query(Parse.User); 
    query.descending("id_client");
    query.limit(1);
    return query.find().then(function(users) {
        return (users.length)? users[0].get("id_client") : 0;
    });
}

// return a promise for users with emailSent flag == false
function usersWithUnsentEmail() {
    var query = new Parse.Query(Parse.User);
    query.equalTo("emailSent", false);
    return query.find();
}

// return a promise to send email to the given user, and to set its 
// emailSent flag = true, and to set its clientId to the passed value
function sendEmailToUser(user, idClient) {
    return sendEmail(user.get("email")).then(function() {
        user.set("emailSent", true);
        user.set("id_client", idClient);
        return user.save();
    });
}

// return a promise to send email to the given email address via an http service
function sendEmail(email) {
    var params = {url: 'http://www.example.com/sendemail.php', params: {email : email} };
    return Parse.Cloud.httpRequest(params);
}


Parse.Cloud.job("test", function(request, response) {
    // Set up to modify user data
    Parse.Cloud.useMasterKey();

    var maxIdClient;
    getMaxId().then(function(result) {
        maxIdClient = result;
        return usersWithUnsentEmail();
    }).then(function(users) {
        var emailPromises = _.map(users, function(user) {
            return sendEmailToUser(user, maxIdClient);
        });
        return Parse.Promise.when(emailPromises);
    }).then(function(results) {
        response.success(results);
    }, function(error) {
        response.error(error);
    });
});

编辑 - 我们在这里特别针对应用程序开发逻辑,而不是承诺的概念,但无论如何都要进行。重述功能要求:我们希望找到一个工作来查找尚未记录在另一个数据库中的用户,由一个名为“emailSent”的标志表示。我们的目标是为这些用户分配一个唯一的ID,并通过电子邮件将他们的信息(现在,我们将说出电子邮件地址和该ID)发送到某个固定目的地。

所以

// getMaxId() from above is almost ready, except the minimum id_client
// value is 20000, so change the line that set this to:
return (users.length)? users[0].get("id_client") : 20000;

// usersWithUnsentEmail() from above is fine
// delete sendEmailToUser() since we're not doing that

// change sendEmail() to take an array of users to be conveyed to
// the other database. Send email about them, then change each user's
// emailSent status and save them
function sendEmail(users) {
    var params = {url: 'http://www.example.com/sendemail.php', params: {users : JSON.stringify(users)} };
    return Parse.Cloud.httpRequest(params).then(function() {
        _.each(users, function(user) {user.set("emailSent", true);});
        return Parse.Object.saveAll(users);
    });
}

// add a function that takes an array of users, updates their
// id_client to be a new, unique value, and sends mail about them
// to a remote server
function synchUsers(users, idMax) {
    _.each(users, function(user) {
        user.set("id_client", idMax);
        idMax += 1;
    });
    return sendEmail(users);
}

// update the job taking all this into account
Parse.Cloud.job("test", function(request, response) {
    // Set up to modify user data
    Parse.Cloud.useMasterKey();

    var maxIdClient;
    getMaxId().then(function(result) {
        maxIdClient = result;
        return usersWithUnsentEmail();
    }).then(function(users) {
        return synchUsers(users, maxIdClient+1);
    }).then(function(results) {
        response.success(results);
    }, function(error) {
        response.error(error);
    });
});