Синхронизация в JS

171
13 ноября 2018, 20:10

Чтоб не устраивать очередной callback-hell и сделать код более плоским ищу аналог питоновского loop.run_until_complete для js. Если вызывать промис из асинхронной функции, то можно воспользоваться await, но вызываться придётся из сторонних колбэков...

function main(){
let response_promise = axios.get("https://api.chucknorris.io/jokes/random") 
// promise
let response = run_until_complete(response_promise) 
// готовый объект, который передается в .then()
}

Для асинхронных функций можно воспользоваться await:

async function async_main() {
   let response = await axios.get("https://api.chucknorris.io/jokes/random")
}

При использовании калбэков и 2х запросов, зависимых друг от друга получается уже 3 колбэка. вот пример на 50 строк:

function onerror(error){
    console.log(error)
}
function onlogin(response) {
        if (response.redir.redirectionURL) {
            $window.location.href=response.redir.redirectionURL
        }
        else if (response.redir.originalURL) {
            $window.location.href=response.redir.originalURL
        } else {
            $location.path('/status/')
        }
}
function onchillistatus(response) {
    var challenge = hex2bin(response.challenge);
    var chapid = '\x00';
    var charpassw = hexMD5(chapid + password + challenge);
    $resource(chilli+'logon',
        {
            username:username,
            response:charpassw,
        },
        {get:{ method: 'JSONP',jsonpCallbackParam:'callback'}}
    ).get(onlogin);
}
function onmikrotikstatus(response){
        var dst = $cookies.get('linkorig') || "/uam/status/";
        if (response.challenge) {
          var charpassw = hexMD5(response.chapid + password + response.challenge);
        } else {
          var charpassw = password;
        }
        $resource($cookies.get('linklogin'),
        {
            target:'jsonp',
            dst:dst,
            username:username,
            password:charpassw,
        },
        {get:{ method: 'JSONP',jsonpCallbackParam:'var'}}).get(onlogin)
        if (response.redir.logoutURL) $cookies.put('linklogout', response.redir.logoutURL);
}
function login(){
      if(ischilli) {
          $resource(chilli+'status', { },
          {get:{ method: 'JSONP',jsonpCallbackParam:'callback'}}
          ).get(onchillistatus,onerror)
      } else {
          $resource($cookies.get('linklogin'),
          {
              target:'jsonp',
          },
          {get:{ method: 'JSONP',jsonpCallbackParam:'var'}}).get(onmikrotikstatus,onerror)
      }
}

Тут уже нельзя прочитать программу сверху вниз. И это только кусочек. А перед ним ещё пару запроса на получение логина и пароля с другого сервера. Получается что нужно написать 7 функций на одно действие пользователя.

Другой пример:

В vue компоненте указать валидатор, а валидатор должен сделать запрос в апи. Валидатор должен вернуть строку, но если положить туда асинхронную функцию, то он вернет промис.

Answer 1

Сделайте login асинхронной и пишите там что хотите:

async function login() {
  if(ischilli) {
    const result = await fetchLogin();
    const result2 = await onmikrotikstatus(result);
  } else {
    const result = await fetchLogin();
    const result2 = await onlogin(result);
  }
}
// хотя код не дождется окончания самого login внутри будет все последовательно
login();

Если нужен onerror, то все в catch

async function login() {
  try {
    if(ischilli) {
      const result = await fetchLogin();
      const result2 = await onmikrotikstatus(result);
    } else {
      const result = await fetchLogin();
      const result2 = await onlogin(result);
    }
  } catch(error) {
    onerror(error)
  }
}
READ ALSO
Vue в data использовать getter текущего объекта

Vue в data использовать getter текущего объекта

Допустим у нас есть такой код

170
При запуске сервера nodejs возникает ошибка

При запуске сервера nodejs возникает ошибка

Делаю всё по книжке "Стек MEAN" но не получается даже привет экспресс Запустить

174
Slider Pro вертикальные минатюры

Slider Pro вертикальные минатюры

как в слайдере Slider Pro сделать вертикальные миниатюры справа как здесь

153
Проблема при скрытии меню

Проблема при скрытии меню

есть хедер с меню, при наведении на лишку появляется меню (изменение стейта, свойство isOpen), в меню много li, каждая это запрос по REST на получение...

160