如何让 response.success() 等待?

How to make response.success() wait?

在下面的 Cloud 函数中,我需要知道 response.success() 的放置位置和方式,以便它在所有工作完成后执行,而不是之前。 我已经检查过该功能是否按预期工作。唯一的问题是我提到的那个。 我正在尝试使用 Promises,但到目前为止我所做的没有奏效。

 Parse.Cloud.define
 ("deleteUnitAndDependencies", function(request, response) {
    var unitListQuery;
    unitListQuery = new Parse.Query("UnitList");
    unitListQuery.equalTo("objectId", request.params.unitID);
    unitListQuery.equalTo("ownerID", request.params.userID);
    unitListQuery.find().then(function(resUnit) {
    var sentenceListQuery,sentenceListStatus;
    sentenceListQuery = new Parse.Query("SentenceList");
    sentenceListQuery.equalTo("unit", resUnit[0]);
    sentenceListStatus = sentenceListQuery.find();
    resUnit[0].destroy({});
    return sentenceListStatus;
    }).then(function(resSentence) {
    var translatListQuery,translatListQStatus;
    translatListQuery = new Parse.Query("TranslatList");
    for (iS = 0; iS < resSentence.length; iS++) {
        if (iS == 0 ) {
            translatListQuery.equalTo("sentence", resSentence[iS]);
            continue;
        }
        translatListQuery = Parse.Query.or(translatListQuery,
                                           (new Parse.Query("TranslatList")).equalTo
                                           ("sentence", resSentence[iS]));
    }
    translatListQStatus = translatListQuery.find();
    for (iS = 0; iS < resSentence.length; iS++) {
        resSentence[iS].destroy({});
    }
    return translatListQStatus;
    }).then(function(resTranslat) {
    for (iT = 0; iT < resTranslat.length; iT++) {
        resTranslat[iT].destroy({});
    }
    });
   });

将函数放入 doSomeBigWork,当它处理完异步内容后,让它调用该函数。

doSomeBigWork(function() {
    response.success();
});

您的代码中有多个部分是 return 承诺的。您需要将这些包含在您的承诺链中。这就像使用 return 语句一样简单。

例如这个区块:

    translatListQStatus = translatListQuery.find();
    for (iS = 0; iS < resSentence.length; iS++) {
        resSentence[iS].destroy({});
    }
    return translatListQStatus;
}).then(function(resTranslat) {
    for (iT = 0; iT < resTranslat.length; iT++) {
        resTranslat[iT].destroy({});
    }
});

您想等待那些 destroy 调用完成。查看 Promise Chaining in Parallel

上的这部分帮助
    var findResults;
    translatListQStatus = translatListQuery.find()
    .then(function(resTranslat) {
        var destroyPromises = [];
        for (iS = 0; iS < resSentence.length; iS++) {
            destroyPromises.push(resSentence[iS].destroy({}));
        }

        // save these so we can return them at the end
        findResults = resTranslat;

        // return a promise here
        return Parse.Promise.when(destroyPromises);
    })
    .then(function() {
        // return the results we saved
        return findResults;
    });

    return translatListQStatus;
}).then(function(resTranslat) {
    var destroyPromises = [];
    for (iT = 0; iT < resTranslat.length; iT++) {
        destroyPromises.push(resTranslat[iT].destroy({}));
    }

    return Parse.Promise.when(destroyPromises);
});

以防有人遇到类似问题,我把我想到的解决方案放在这里。据我目前检查的那样,它正在按照我想要的方式工作。 如果一些 promise-expert 阅读本文并对改进它有意见和建议,请告诉我们。

Parse.Cloud.define
("deleteUnitAndDependencies", function(request, response) {
 var unitListQuery;
 unitListQuery = new Parse.Query("UnitList");
 unitListQuery.equalTo("objectId", request.params.unitID);
 unitListQuery.equalTo("ownerID", request.params.userID);

 unitListQuery.find().then
 (function(resUnit) {
  // If there is no UNIT we return an error.
  if (!resUnit.length) response.error("NO-UNIT");

  var sentenceListQuery;
  sentenceListQuery = new Parse.Query("SentenceList");
  sentenceListQuery.equalTo("unit", resUnit[0]);

  sentenceListQuery.find().then
  (function(resSentence) {
   var translatListQuery,tmpQuery;
   translatListQuery = new Parse.Query("TranslatList");

   for (iS = 0; iS < resSentence.length; iS++) {
    if (iS == 0 ) {
        translatListQuery.equalTo("sentence", resSentence[iS]);
        continue;
    }

    tmpQuery = new Parse.Query("TranslatList");
    tmpQuery.equalTo("sentence", resSentence[iS]);
    translatListQuery = Parse.Query.or(translatListQuery,tmpQuery);
   }

   translatListQuery.find().then
   (function(resTranslat) {
    var destroyPromises = [];
    for (iT = 0; iT < resTranslat.length; iT++) {
        destroyPromises.push(resTranslat[iT].destroy({}));
    }
    return Parse.Promise.when(destroyPromises);
    }).then
   (function() {
    var destroyPromises = [];
    for (iS = 0; iS < resSentence.length; iS++) {
        destroyPromises.push(resSentence[iS].destroy({}));
    }
    return Parse.Promise.when(destroyPromises);
    }).then
   (function() {
    return resUnit[0].destroy({});
    }).then(response.success);
   });
  });
 });

米歇尔,恭喜你成功了。对于使用 promises 才几天的人来说,这是一个不小的成就。

您会发现,通过创建 destroy() 实用程序,您可以避免代码重复并直接压缩主例程。

有了这个实用程序和进一步的 simplifications/rearrangements,我得到了这个:

Parse.Cloud.define("deleteUnitAndDependencies", function(request, response) {
    //A utility function that gets called twice
    function destroy(arr) {
        return Parse.Promise.when(arr.map(function(r) {
            return r.destroy({});
        }));
    }
    var unitListQuery = new Parse.Query("UnitList");
    unitListQuery.equalTo("objectId", request.params.unitID);
    unitListQuery.equalTo("ownerID", request.params.userID);
    unitListQuery.find().then(function(resUnit) {
        var sentenceListQuery = new Parse.Query("SentenceList");
        sentenceListQuery.equalTo("unit", resUnit[0]);
        return sentenceListQuery.find().then(function(resSentence) {
            var translatListQuery = new Parse.Query("TranslatList");
            translatListQuery.equalTo("sentence", resSentence[0]);
            for (var iS = 1; iS < resSentence.length; iS++) {//loop counter now starts at 1
                translatListQuery = Parse.Query.or(translatListQuery, (new Parse.Query("TranslatList")).equalTo("sentence", resSentence[iS]));
            }
            return translatListQuery.find().then(destroy).then(function() {
                return destroy(resSentence.concat(resUnit[0]));
            });
        });
    }).then(response.success);
});

未测试

编辑

由于销毁似乎不需要互相等待,所以你应该可以做两次 .concat() 技巧,并调用一次 destroy()

return translatListQuery.find().then(function(resTranslat) {
    return destroy(resTranslat.concat(resSentence).concat(resUnit[0]));
});