2015-02-23 1 views
2

Я использую Parse для представления состояния пивного бочонка (между прочим). Я хотел бы проверить уведомления пользователя, хранящиеся в таблице «Уведомления», чтобы узнать, хотят ли они получать уведомление, когда бочонок заполнен.Parse Cloud: запрос не работает в экспортированной функции из save() обратного вызова

У меня есть вся логика настройки параметров уведомлений пользователя, а также отправка уведомлений в облако/notifications.js. Вся логика обновления бочонка находится в облаке/пиве.js. Я создал экспортированную функцию, называемую sendKegRefillNotification, которая выполняет query.find() в таблице уведомлений и получает вызов из beer.js.

Проблема заключается в том, что она не выполняет query.find(), когда я вызываю функцию из beer.js, однако, когда я вызываю одну и ту же функцию из задания в notifications.js, она работает просто отлично ,

main.js:

require("cloud/beer.js"); 
require("cloud/notifications.js"); 

beer.js:

var notify = require("cloud/notifications.js"); 

var Keg = Parse.Object.extend("Keg"); 

var fillKeg = function(beerName) { 
    var promise = new Parse.Promise(); 

    var keg = new Keg(); 
    keg.set("beerName", beerName) 
    keg.set("kickedReports", []); 
    keg.save(null, { useMasterKey: true }).then(function(keg) { 
     console.log("Keg updated to " + beerName + "."); 
     promise.resolve(keg); 
     notify.sendKegRefillNotification(keg); 
    }, 
    function(keg, error) { 
     promise.reject(error); 
    }); 

    return promise; 
} 

Parse.Cloud.define("beerFillKeg", function(request, response) { 
    var beerName = request.params.name; 
    if (!beerName) { 
     response.error("No beer was specified."); 
     return; 
    } 
    if (!util.isUserAdmin(request.user)) { 
     response.error("User does not have permission to update the keg."); 
     return; 
    } 
    fillKeg(beerName).then(function(keg) { 
     kegResponse(keg).then(function(result) { 
      response.success(result); 
     }); 
    }, 
    function(error) { 
     response.error(error); 
    }); 
}); 

function kegResponse(keg) { 
    var promise = new Parse.Promise(); 

    var result = { 
     id: keg.id, 
     beer: { 
      name: keg.get("beerName") 
     }, 
     filled: keg.createdAt, 
     kickedReports: [] 
    }; 

    var kickedReports = keg.get("kickedReports"); 
    if (!kickedReports || kickedReports.length == 0) { 
     promise.resolve(result); 
    } else { 
     util.findUsers(kickedReports).then(function(users) { 
      result.kickedReports = util.infoForUsers(users); 
      promise.resolve(result); 
     }, function(users, error) { 
      console.log(error); 
      promise.resolve(result); 
     }); 
    } 
    return promise; 
} 

notifications.js:

var Keg = Parse.Object.extend("Keg"); 
var Notification = Parse.Object.extend("Notifications"); 

exports.sendKegRefillNotification = function(keg) { 
    var beerName = keg.get("beerName"); 
    console.log("Sending notifications that keg is refilled to '" + beerName + "'."); 

    var promise = new Parse.Promise(); 

    var query = new Parse.Query(Notification); 
    query.include("user"); 
    query.equalTo("keg_filled", true); 
    query.find({ useMasterKey: true }).then(function(notifications) { 
     console.log("Found notifications!"); 
     promise.resolve("Found notifications!"); 
    }, 
    function(notifications, error) { 
     console.error("No notifications"); 
     console.error(error); 
     promise.reject(error); 
    }); 

    return promise; 
} 

Parse.Cloud.job("beerSendRefillNotification", function(request, status) { 
    var query = new Parse.Query(Keg); 
    query.descending("createdAt"); 
    query.first().then(function(keg) { 
     if (!keg) { 
      status.error("No keg"); 
      return; 
     } 

     exports.sendKegRefillNotification(keg); 
    }, 
    function(keg, error) { 
     response.error(error); 
    }); 
}); 

Когда я запускаю работу "beerSendRefillNotification" из приборной панели Разбор, Я могу сказать, что query.find() получает вызов, потому что он печатает «Найдено уведомлений!»:

E2015-02-23T06:59:49.006Z]v1564 Ran job beerSendRefillNotification with: 
    Input: {} 
    Result: success/error was not called 
I2015-02-23T06:59:49.055Z]false 
I2015-02-23T06:59:49.190Z]Sending notifications that keg is refilled to 'test'. 
I2015-02-23T06:59:49.243Z]Found notifications! 

Однако, когда я называю функцию облака «beerFillKeg», это происходит не потому, что не печатает «Найдено уведомлений!». или «Нет уведомлений»:

I2015-02-23T07:00:17.414Z]v1564 Ran cloud function beerFillKeg for user HKePOEWZvC with: 
    Input: {"name":"Duff"} 
    Result: {"beer":{"name":"Duff"},"filled":{"__type":"Date","iso":"2015-02-23T07:00:17.485Z"},"id":"olLXh0F54E","kickedReports":[]} 
I2015-02-23T07:00:17.438Z]false 
I2015-02-23T07:00:17.523Z]Keg updated to Duff. 
I2015-02-23T07:00:17.525Z]Sending notifications that keg is refilled to 'Duff'. 

ответ

2

Я, наконец, понимаю это. В sendKegRefillNotification вы вызываете query.find({...}), а затем возвращаете объект. То, что find является асинхронным, и вы ничего не предпринимаете, чтобы ждать результата. Я думаю, вам нужно вернуть вызов функции find, а не объект, установленный в этом методе.

Другими словами, вы бежите, оставляя позади какой-то код для запуска асинхронного программирования.

Редактировать: Я понимаю, что вы пытались сделать. Это имеет смысл. Вы определили обещание и подумали, что вызывающий будет ждать обещания. Проблема в том, что обещание определено в асинхронном блоке. Он пока не имеет никакого значения в момент, когда вызывающий абонент получает его.

+1

Да, я понимаю сейчас. Было ошибкой пытаться создать обещание и установить его, но я должен объединить обещания вместе. Это исправило это, спасибо! – Mel

0

Похоже Parse не позволяет запускать запрос внутри обратного вызова из экономии(). Когда я переместил «notify.sendKegRefillNotification (кег)»; к внешней стороне обратного вызова, это сработало.

var fillKeg = function(beerName) { 
    var promise = new Parse.Promise(); 

    var keg = new Keg(); 
    keg.set("beerName", beerName) 
    keg.set("kickedReports", []); 
    keg.save(null, { useMasterKey: true }).then(function(keg) { 
     console.log("Keg updated to " + beerName + "."); 
     console.log("Send notifications."); 
     promise.resolve(keg); 
    }, 
    function(keg, error) { 
     promise.reject(error); 
    }); 

    notify.sendKegRefillNotification(keg); // Now this works 

    return promise; 
} 

Может ли кто-нибудь пролить свет на то, почему это сработало?

+0

Этот ответ мне неприятен. Ограничение такого рода будет полностью противоречить духу Парса. (Я использую запросы в своих собственных обратных вызовах сохранения, но логика - редкий случай, и я не могу на самом деле быть уверенным, что это работает.) – piojo

Смежные вопросы