Я пытаюсь понять, как использовать обещания в написанном мной тесте. Я использую простые старые обещания в браузере. Нет библиотек (пока)

Тест требует асинхронной связи с сервером, где я получаю ответ сервера через обратный вызов.

У меня есть объект сервера, где я регистрирую обратный вызов следующим образом:

server.onresponse = function(data){
  //do stuff with data
}

Тест требует отправки на сервер серии команд, которые меняются в зависимости от ответа сервера. Я отправляю команды на сервер вот так

server.sendCommand({data:"do something"})

На основе команды сервер вызовет обратный вызов onresponse. Мне нужно было бы прочитать данные, которые отправил сервер, чтобы решить, какой должна быть следующая команда.

Взаимодействие должно быть чем-то вроде

  • отправить команду 1 и ждать
  • обрабатывать данные из обратного вызова onresponse
  • отправьте команду 2 и ждите
  • обрабатывать данные из обратного вызова onresponse

Я хотел бы использовать обещания, чтобы сделать это взаимодействие более понятным. Что-то вроде серии .then() s.

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

Есть ли способ сделать это с помощью обещаний? Я тоже начал читать генераторы. Это тоже поможет?

Благодарность

0
ceiling cat 31 Дек 2017 в 01:13

2 ответа

Лучший ответ

Вы могли бы иметь что-то вроде этого:

function sendCommand(data) {
    return new Promise(function(resolve,reject) {
         server.onresponse = resolve;
         server.sendCommand(data);
    });
}

И используйте это так:

sendCommand({data:"do something"})
.then(function(data) {
    console.log(data);
    return sendCommand({data:"do something else "})
})
.then(function(data) {
    console.log(data);
})
1
Federkun 30 Дек 2017 в 22:40

Вы можете написать вспомогательную функцию, чтобы делать то, что вы описали. Передайте команду, и она вернет Promise, который разрешается с ответом от сервера. Если есть обратный вызов обработки ошибок, вы также должны использовать его. Например, назовем его server.onerror. Вы должны заменить его на подходящий обработчик.

function sendCommand(cmd) {
  const promise = new Promise((resolve, reject) => {
    server.onresponse = resolve;
    server.onerror = reject;
  });
  server.sendCommand(cmd);
  return promise;
}

Вы бы использовали его так же, как вы описали, цепочку обещаний. Конечно, вы, вероятно, захотите что-то сделать с ответом, а не просто запустить следующую команду. И всегда не забывайте обрабатывать любые ошибки в конце с помощью catch!

sendCommand({data: "do thing 1"})
  .then((response) => sendCommand({data: "do thing 2"}))
  .then((response) => sendCommand({data: "do thing 3"}))
  .then((response) => console.log("All done!"))
  .catch((error) => console.log("Oops!"));
0
kamoroso94 30 Дек 2017 в 22:45