Синхронный API в браузере, содержащий HTTP-вызов? - PullRequest
0 голосов
/ 14 апреля 2020

localStorage является синхронным, и если myStore также, то это будет работать:

// Example #1
var store = myStore||localStorage;
var item  = store.getItem("data");

Однако, если myStore имеет асинхронный элемент, он не будет работать, поэтому код работает для обоих, мне нужно сделать что-то вроде этого:

// Example #2
(async () => {
    var store = myStore||localStorage;
    var item  = await store.getItem("data");
})();

(то есть async / await работает как для синхронного, так и для асинхронного кода).


Теперь скажем это мой асинхронный код где-то в myStore:

fetch('http://localhost:3000/getItem', {
        method: 'POST',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        },
    body: JSON.stringify({ key: key })
});

Или какой-то xhr эквивалент .. Возможно ли записать его как Пример # 1 , или я вынужден сделать это как Пример # 2 если у меня где-нибудь есть HTTP-вызов?

В основном я пытаюсь реализовать API-интерфейс localStorage через HTTP в браузере, и я предпочел бы, чтобы он вел себя и быть написанным в точности как нативный API-интерфейс localStorage (насколько это возможно) и не требовать изменения кода localStorage при представлении myStore, кроме: myStore||localStorage.


Если это невозможно или не рекомендуется, почему

1 Ответ

1 голос
/ 14 апреля 2020

Вы можете использовать await только внутри функции asyn c, а функции asyn c всегда возвращают Promise .

Вы можете подумать о том, чтобы сделать что-то вроде этого:

class Store {
  // ...
  async getItem(key){
    return await fetch('http://localhost:3000/getItem', {
      method: 'POST',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ key: key })
    }).then((res) => res.text());
  }
}

Но ключевое слово asyn c заставит возвращаемое значение getItem быть обещанием. Таким образом, даже если вы вернете не-обещание (в данном случае текст ответа на запрос), оно будет заключено в Promise.resolve (), создав новое разрешенное обещание.

Следовательно, это будет не работает с первым примером, потому что переменная item должна содержать некоторые доступные данные, а не Promise.

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

...