简体   繁体   English

如何使这个 Javascript API 响应全局的 output ?

[英]How do I make the output of this Javascript API response global?

I'm trying to receive the output for the following code where the cc variable would log a value into the empty global country variable.我正在尝试接收 output 以获取以下代码,其中 cc 变量会将值记录到空的全局国家变量中。 Afterwards print it to the console, however it isn't working.然后将其打印到控制台,但它不起作用。 How would I make the local variable cc here to global/give the global variable country a value?我如何在这里使局部变量 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);

It seems like your problem has to do with the asynchronous nature of your code.您的问题似乎与代码的异步性质有关。 Let me explain.让我解释。

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

The fetch function is asynchronous.获取 function 是异步的。 That's why you need the .then methods.这就是您需要.then方法的原因。 This means that while the fetch function runs, JavaScript doesn't stop the rest of the program, and instead moves on while fetch() runs in the background.这意味着当 fetch function 运行时,JavaScript 不会停止程序的 rest,而是在fetch()在后台运行时继续。 Hence, when you console.log(country) , it's still of the original value (empty string).因此,当您console.log(country)时,它仍然是原始值(空字符串)。

To answer your question, you can use Promise s to log the value of cc.要回答您的问题,您可以使用Promise记录 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))

You can find out more about promises at the MDN docs您可以在MDN 文档中找到有关 Promise 的更多信息

The problem with your currently call console.log(country) before country is set to response.countryCode .您当前调用console.log(country)country设置为response.countryCode之前的问题。

You could solve this by placing your code inside an async IIFE in the following manner:您可以通过以下方式将代码放入异步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); })();


If you have another script with function definitions that depends on county be sure to accept it as parameter and don't pull the data from a global variable.如果您有另一个脚本,其中 function 定义取决于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
}

You can then call you other script inside the IIFE by just passing the value.然后,您可以通过传递值来调用 IIFE 中的其他脚本。

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

If for some reason want a global variable really bad.如果出于某种原因想要一个全局变量真的很糟糕。 You should place the promise inside this variable, not the value.您应该将 promise 放在此变量中,而不是值中。 With this promise you can pass the value, as well as notify other scripts when this value is available.使用此 promise 您可以传递该值,并在该值可用时通知其他脚本。

// 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);
});

Your problem come from the fact that your fetch is an asynchrone function, with a promise.您的问题来自这样一个事实,即您的 fetch 是异步 function,带有 promise。

What you want to do is that (I suppose)你想做的是(我想)

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);

But, since you use an async function, this is what is done:但是,由于您使用异步 function,因此可以这样做:

//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);

How to fix that?如何解决? it depend.看情况。 If your console.log is triggered by a button, make it wait for country to be filled如果您的console.log 是由按钮触发的,请等待填写国家/地区

else, put your code in the last then, or use Promise.all() (documentation here )否则,将您的代码放在最后,或使用Promise.all()此处的文档)

console.log is happening before fetch is resolved. console.logfetch解决之前发生。 Try this:尝试这个:

let country = '';
fetch('https://extreme-ip-lookup.com/json/')
    .then(res => res.json())
    .then(res => country = res.countryCode)
    .then(() => console.log(country))
  

fetch returns a Promise , hence the .then() chain in your question. fetch返回一个Promise ,因此是您问题中的 .then .then()链。

But if you stepped into Promise Land, you won't find out.但是如果你踏入Promise Land,你就不会发现了。 You'll have to do everything with Promises.你必须用 Promises 做所有事情。

But you might split you logic into small manageable parts like here但是您可能会将您的逻辑拆分为可管理的小部分,例如这里

 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) })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM