Проблема с пониманием ошибки, связанной с обещаниями и областью действия

Я работаю над небольшим веб-интерфейсом для фотона частицы, который я настроил в качестве учебного упражнения для js.

У меня ошибка, и я не могу понять, почему.

Ранее в коде я использовал скрипт для входа в систему https://docs.particle.io/reference/javascript/

var particle = new Particle();
var token;

particle.login({username: 'user@email.com', password: 'pass'}).then(
  function(data) {
    token = data.body.access_token;
  },
  function (err) {
    console.log('Could not log in.', err);
  }
);

В этом примере я использую element.login(), а затем сразу использую.then для него. Это работает просто отлично, и я получаю токен, который я ожидаю.

Далее я хочу перечислить все мои устройства, я использую пример кода из документации, чтобы сделать это:

var devicesPr = particle.listDevices({ auth: token });

devicesPr.then(
  function(devices){
    console.log('Devices: ', devices);
  },
  function(err) {
    console.log('List devices call failed: ', err);
  }
);

Это также работает отлично. Нет проблемы.

Вот моя проблема:

Я подумал про себя: "Ну и дела, почему бы мне просто не избавиться от этого var devicesPr и просто немедленно вызвать его". Итак, я стараюсь:

particle.listDevices({auth: token}).then(
    function(devices){
        console.log('Devices: ', devices);
    },
    function(err) {
        console.log('List of devices call failed: ', err);
    }
);

Теперь я получаю сообщение об ошибке:

init.js:23 List of devices call failed:  {statusCode: 400, errorDescription: "HTTP error 400 from /v1/devices - The access token was not found", error: Error: Unsuccessful HTTP response
    at Request.<anonymous> (http://cdn.jsdelivr.net/particle-api-j…, body: {…}}
init.js:11 API call completed on promise resolve: API KEY

Так что я замечаю, что кажется, что запрос списка устройств выполняется до того, как генерируется токен авторизации. Я полагаю, что это имеет смысл, поскольку в документации об обещаниях постоянно упоминается, что они асинхронны.

Я просто запутался, почему я не вижу такой же возможной ошибки, когда я сначала делаю ее переменной, а затем вызываю.then? Знает ли он как-то ждать, пока не появится маркер аутентификации, если я сначала сохраню обещание для переменной?

Спасибо!

Полный код неисправности при запуске:

"use strict";

//var Particle = require('particle-api-js');
var particle = new Particle();
var token;


particle.login({username: 'MYEMAIL', password:'MYPASSWORD'}).then(
  function(data){
    token = data.body.access_token;
    console.log('API call completed on promise resolve: ', token);
  },
  function(err) {
    console.log('API call completed on promise fail: ', err);
  }
);

particle.listDevices({auth: token}).then(
    function(devices){
        console.log('Devices: ', devices);
    },
    function(err) {
        console.log('List of devices call failed: ', err);
    }
);

1 ответ

Ты не цепляешься listDevices с token получил от particle.login - ты звонишь particle.listDevices синхронно, до token был заселен. Запрос на получение токена, возможно, был отправлен, но асинхронный .then что заселено token конечно еще не бежал.

Вместо этого используйте .then связать listDevices после particle.login, как это:

var particle = new Particle();
particle.login({username: 'MYEMAIL', password:'MYPASSWORD'})
  .then(data => {
    const token = data.body.access_token;
    console.log('API call completed on promise resolve: ', token);
    // Return the listDevices promise so `.then` can be called on it below:
    return particle.listDevices({auth: token});
  })
  .catch(err => console.log('API call completed on promise fail: ', err))
  .then(devices => console.log('Devices: ', devices))
  .catch(console.log('List of devices call failed: ', err));
Другие вопросы по тегам