Почему клиент не получает данные, которые извлекает сервер?

#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(); .