Как сделать вывод этого Javascript ответа API глобальным? - PullRequest
0 голосов
/ 10 июля 2020

Я пытаюсь получить вывод для следующего кода, в котором переменная cc записывает значение в пустую глобальную переменную страны. Затем распечатайте его на консоли, но он не работает. Как мне сделать локальную переменную cc здесь глобальной / присвоить глобальной переменной country значение?

var country = '';
fetch('https://extreme-ip-lookup.com/json/')
.then( res => res.json())
.then(response => {
    var cc = (response.countryCode);
    country = cc;
 });
 console.log(country);

Ответы [ 5 ]

1 голос
/ 10 июля 2020

Проблема с вашим текущим вызовом console.log(country) перед country установлена ​​на response.countryCode.

Вы можете решить эту проблему, поместив свой код в асинхронный c IIFE следующим образом:

(async () => {
  const response = await fetch('https://extreme-ip-lookup.com/json/');
  const ipData   = await response.json();
  const country  = ipData.countryCode;

  // place all code that uses `country` in here
  console.log(country);
})();

Если у вас есть другой сценарий с определениями функций, зависящими от county, обязательно примите его как параметр и не извлекайте данные из глобальной переменной.

// helper_functions.js

// Bad
function someFunctionThatUsesCountry() {
  console.log(country); // <- don't expect the global to be set
}

// Good
function someFunctionThatUsesCountry(country) {
  console.log(country); // pull country ^ from the parameter list
}

Затем вы можете позвонить вам другой сценарий внутри IIFE, просто передав значение.

(async () => {
  // ...
  someFunctionThatUsesCountry(country);
})();

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

// script_1.js
window.country = fetch('https://extreme-ip-lookup.com/json/')
                 .then(response => response.json())
                 .then(ipData => ipData.countryCode);
// script_2.js (must be loaded after script_1.js)
window.country.then(country => { // <- wait until country is available
  // do stuff with country
  console.log(country);
});
1 голос
/ 10 июля 2020

Похоже, ваша проблема связана с асинхронным характером вашего кода. Позвольте мне объяснить.

var country = '';
fetch('https://extreme-ip-lookup.com/json/')
    .then( res => res.json())
    .then(response => {
        var cc = (response.countryCode);
        country = cc;
    });
console.log(country);

Функция выборки является асинхронной. Вот почему вам нужны методы .then. Это означает, что пока выполняется функция выборки, JavaScript не останавливает остальную часть программы, а вместо этого продолжает работу, пока fetch() выполняется в фоновом режиме. Следовательно, когда вы console.log(country), оно все еще имеет исходное значение (пустая строка).

Чтобы ответить на ваш вопрос, вы можете использовать Promise s для регистрации значения cc.

var country = '';
const fetchPromise = fetch('https://extreme-ip-lookup.com/json/')
    .then( res => res.json())
    .then(response => {
        var cc = (response.countryCode);
        country = cc;
    });

Promise.resolve(fetchPromise) // Waits for fetchPromise to get its value
    .then(() => console.log(country))

Подробнее об обещаниях можно узнать в документации MDN

0 голосов
/ 10 июля 2020

fetch возвращает Promise, следовательно, цепочку .then() в вашем вопросе.

Но если вы вошли в Promise Land, вы не узнаете. Вам придется делать все с помощью Promises.

Но вы можете разделить logi c на небольшие управляемые части, как здесь

console.clear()

let cached = null;
const lookup         = ()          => fetch('https://extreme-ip-lookup.com/json/');
// Caching json and not the fetch promise, because
// https://stackoverflow.com/a/54731385/476951
const getJson        = ()          => cached = cached || lookup() .then(response => response.json());
const getParameter   = (parameter) => getJson()                   .then(json => json[parameter]);
const getCountry     = ()          => getParameter('country')     .then(value => value);
const getCountryCode = ()          => getParameter('countryCode') .then(value => value);


getCountryCode().then(countryCode => {
  console.log('countryCode:', countryCode)
})

getCountry().then(country => {
  console.log('country:', country)
})

getParameter('city').then(city => {
  console.log('city:', city)
})
0 голосов
/ 10 июля 2020

console.log происходит до разрешения fetch. Попробуйте это:

let country = '';
fetch('https://extreme-ip-lookup.com/json/')
    .then(res => res.json())
    .then(res => country = res.countryCode)
    .then(() => console.log(country))
  
0 голосов
/ 10 июля 2020

Ваша проблема связана с тем, что ваша выборка является асинхронной функцией с обещанием.

То, что вы хотите сделать, это (я полагаю)

var country = '';
//then
fetch('https://extreme-ip-lookup.com/json/')
.then( res => res.json())
.then(response => {
    var cc = (response.countryCode);
    country = cc;
 });
//then
console.log(country);

Но, поскольку вы используете функцию asyn c, вот что делается:

//first
var country = '';
//second
fetch('https://extreme-ip-lookup.com/json/')
.then( res => res.json())
.then(response => {
    //fourth
    var cc = (response.countryCode);
    country = cc;
 });
//third
console.log(country);

Как это исправить? это зависит. Если ваш console.log запускается кнопкой, заставьте его ждать заполнения страны

иначе, введите свой код в последнее then или используйте Promise.all() (документация здесь )

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...