#javascript #node.js #promise #client-server
#javascript #node.js #обещание #клиент-сервер
Вопрос:
Я никогда раньше не работал над подобными вещами, и я как бы прыгнул вглубь, но я чувствую, что я действительно близок. Я пытаюсь добавить динамически заполняемый список выбора в диалоговое окно редактирования узла red node. Я написал метод в клиенте, который вызывает метод, который я написал на сервере. Вызов выполняется. Сервер извлекает данные (подтверждается с помощью отладочной печати на консоль), но клиент получает что-то другое, кроме данных. Раньше я не очень разбирался в javascript, но, согласно моему пониманию обещаний, кажется, что данные должны быть отправлены клиенту, поэтому я не понимаю, чего мне не хватает.
Серверный метод в server.js:
getCircles() {
var node = this;
return node.updateSession(function (session) {
return life360.circles(session)
.then(circles => {
console.log("this gets called after the end of the main stack. the value received and returned is: " JSON.stringify(circles));
return circles;
})
});
}
Сервер «требует» .. /index.js , который имеет:
/**
* Fetch the user's circles
*/
module.exports.circles = function (session) {
if (!session) throw new Error("session not specified");
return new Promise((resolve, reject) => {
const LIFE360_CIRCLES_URL = "https://api.life360.com/v3/circles"
const options = {
url: LIFE360_CIRCLES_URL,
headers: {
'Authorization': `${session.token_type} ${session.access_token}`
},
json: true
};
// console.log(`Fetching circles at ${LIFE360_CIRCLES_URL}`);
request(options)
.then(response => {
let circles = response.body.circles;
console.log("Returning circles: " JSON.stringify(circles));
resolve(circles);
});
});
}
Метод клиента, который вызывает метод сервера ( getCircles
) в location.js:
let circles = node.server.getCircles();
console.log("circles = " JSON.stringify(circles));
Вот что я получаю в журнале (я отредактировал идентификаторы, хотя не знаю, нужно ли мне это):
circles = {"isFulfilled":false,"isRejected":false}
Returning circles: [{"id":"xxxxxxxx","name":"Rob's Homes","color":"da22d5","type":"basic","createdAt":"1379025809","memberCount":"4","unreadMessages":"0","unreadNotifications":"0","features":{"ownerId":null,"skuId":null,"premium":"0","locationUpdatesLeft":0,"priceMonth":"0","priceYear":"0","skuTier":null}},{"id":"xxxxxxxx","name":"Rob's Family","color":"f05929","type":"basic","createdAt":"1393782349","memberCount":"4","unreadMessages":"0","unreadNotifications":"0","features":{"ownerId":null,"skuId":null,"premium":"0","locationUpdatesLeft":0,"priceMonth":"0","priceYear":"0","skuTier":null}},{"id":"xxxxxxxx","name":"Leach Family","color":"7f26c2","type":"basic","createdAt":"1393785316","memberCount":"6","unreadMessages":"0","unreadNotifications":"0","features":{"ownerId":null,"skuId":null,"premium":"0","locationUpdatesLeft":0,"priceMonth":"0","priceYear":"0","skuTier":null}}]
this gets called after the end of the main stack. the value received and returned is: [{"id":"xxxxxxxx","name":"Rob's Homes","color":"da22d5","type":"basic","createdAt":"1379025809","memberCount":"4","unreadMessages":"0","unreadNotifications":"0","features":{"ownerId":null,"skuId":null,"premium":"0","locationUpdatesLeft":0,"priceMonth":"0","priceYear":"0","skuTier":null}},{"id":"xxxxxxxx","name":"Rob's Family","color":"f05929","type":"basic","createdAt":"1393782349","memberCount":"4","unreadMessages":"0","unreadNotifications":"0","features":{"ownerId":null,"skuId":null,"premium":"0","locationUpdatesLeft":0,"priceMonth":"0","priceYear":"0","skuTier":null}},{"id":"xxxxxxxx","name":"Leach Family","color":"7f26c2","type":"basic","createdAt":"1393785316","memberCount":"6","unreadMessages":"0","unreadNotifications":"0","features":{"ownerId":null,"skuId":null,"premium":"0","locationUpdatesLeft":0,"priceMonth":"0","priceYear":"0","skuTier":null}}]
Почему я не получаю значение, указанное в консоли, из серверного метода в клиенте?
Я пытался поместить ‘resolve’ в разные места, но, похоже, не могу понять, куда его поместить, чтобы превратить обещание в содержимое на стороне клиента.
В ходе эксперимента я попытался предоставить метод обратного вызова для getCircles
этого node.send([{payload: circles}])
, и это привело к отправке данных circle из узла red node, над которым я работаю. Затем я попытался просто заставить его возвращать круги, и я все еще получаю неразрешенный объект promise.
Есть еще один метод, называемый getCircle в ../index.js и location.js использует это для извлечения данных участника, что работает… Может быть, мне нужно отредактировать getCircles для построения и возврата данных (хэш идентификаторов кругов -> имена кругов), которые я планировал создать после получения данных круга?
Комментарии:
1. Не зная точной взаимосвязи между серверным сценарием и клиентским сценарием, из консоли очевидно, что
getCircles()
метод на стороне клиента возвращает обещание. Вам просто нужно обработать это как любое другое обещание и получить значение от его выполнения.2. По вашему коду
circles
это будет обещание, которое не было выполнено.3. Прохладный. Да, я, очевидно, не знаю, что я делаю. Я пытался вставить resolve в пару мест, но я получил ошибки о том, что метод resolve не существует. Теперь, когда я знаю, что это правильное направление, я посмотрю поближе. Я предположил, что выполнение false означает, что оно не было возвращено.
4. Похоже, разрешение не определено на сервере, потому что обещание находится в файле различий, который «требуется» в верхней части кода сервера? Может быть, мне нужно создать отдельный метод, который возвращает разрешенный ответ и отправляет его обратно.
5. Нет, функция resolve актуальна только при создании promise, а не при его обработке. Обработка обещания — это то, что вы делаете в серверной
getCircles()
функции,life360.circles(session)
возвращает обещание, и вы обрабатываете его с помощью егоthen()
метода. Просто сделайте то же самое в своем клиентском скрипте, т.е.node.server.getCircles().then(circles => console.log(circles))
Вместоlet circles = node.server.getCircles();
.