返回 GET 值并将其存储在 JS 中的变量中

Posted

技术标签:

【中文标题】返回 GET 值并将其存储在 JS 中的变量中【英文标题】:Return GET value and store it in a variable in JS 【发布时间】:2020-06-10 07:03:35 【问题描述】:

请注意,我是 JS 的新手,所以请期待您能想象到的任何偏差。

话虽如此,我正在尝试在 JS 中创建一个函数。这由三部分组成,但最终目标是用一些外部数据填充select

第一个是 GET。在这里,我调用了一个外部 API 来询问配置文件的总数。一切似乎都工作得很好,但是每当我在函数之外执行console.log(totalProfiles) 时,它的值似乎是未定义的。我尝试在最后添加return,但这不是解决方案。

var billingArray = [];
var billingProfiles = [];
var billingSelect = document.getElementById('billingSelect');
(function()
    $.ajax(
        url: url,
        method: 'GET',
        crossDomain: true,
        withCredentials: true,
        dataType: 'JSON',
        headers: 
            'Authorization': 'Basic '+token,
        
    )
    .done(function(response)  billingArray.push(response); var totalProfiles = billingArray[0]['total_count']; return totalProfiles; )
    .fail(function(jqXHR, textStatus, errorThrown)  console.log(textStatus); );
);

使用 totalProfiles,然后我会调用相同的 URL,这次是把所有的配置文件存储在一个数组中:

(function(totalProfiles)
    $.ajax(
        url: url+totalProfiles,
        method: 'GET',
        crossDomain: true,
        withCredentials: true,
        dataType: 'JSON',
        headers: 
            'Authorization': 'Basic '+token,
        
    )
    .done(function(response)  billingProfiles.push(response); )
    .fail(function(jqXHR, textStatus, errorThrown)  console.log(textStatus); );
);

最后一部分包括通过 for 填充 select

function(billingprofiles) 
    for (var i = 0; i < billingProfiles.length(); i++) 
        var billingProfileId = billingProfiles[i]["ngcp:billingprofiles"]["id"];
        var billingProfileName = billingProfile[i]["ngcp:billingprofiles"]["name"];

        var opt = document.createElement("option");
        opt.value() = billingProfileId;
        opt.textContent() = billingProfileName;
        dropdown.appendChild(opt);
    
);

这里的问题是我不知道如何将 totalProfiles 带出函数,所以每当进程到达第二个时,由于变量未定义而失败。

这就是全部,你可以期待我之前谈到的那些异常。我认为这会起作用,但我开始怀疑我打算这样做的方式也可能是问题的一部分:

var billingArray = [];
var billingProfiles = [];
var billingSelect = document.getElementById('billingSelect');
var totalProfiles;

//Fetch total number of profiles
(function() 
  $.ajax(
    url: url,
    method: 'GET',
    crossDomain: true,
    withCredentials: true,
    dataType: 'JSON',
    headers: 
      'Authorization': 'Basic ' + token,
    
  ).done(function(response) 
    billingArray.push(response);
    var totalProfiles = billingArray[0]['total_count'];
    return totalProfiles;
  ).fail(function(jqXHR, textStatus, errorThrown) 
    console.log(textStatus);
  );
)().done(function(totalProfiles) 
  $.ajax(
    url: url + totalProfiles,
    method: 'GET',
    crossDomain: true,
    withCredentials: true,
    dataType: 'JSON',
    headers: 
      'Authorization': 'Basic ' + token,
    
  ).done(function(response) 
    billingProfiles.push(response);
  ).fail(function(jqXHR, textStatus, errorThrown) 
    console.log(textStatus);
  );
)().done(function(billingprofiles) 
  for (var i = 0; i < billingProfiles.length(); i++) 
    var billingProfileId = billingProfiles[i]["ngcp:billingprofiles"]["id"];
    var billingProfileName = billingProfile[i]["ngcp:billingprofiles"]["name"];

    var opt = document.createElement("option");
    opt.value() = billingProfileId;
    opt.textContent() = billingProfileName;
    billingSelect.appendChild(opt);
  
).fail(function(jqXHR, textStatus, errorThrown) 
  console.log(textStatus);
);

一些注释可以更好地解释我这样做的内容和原因: 1.在每个.done之前我必须写()以避免这个错误

(中间值).done 不是函数

    我现在遇到的错误发生在.done(function(totalProfiles)

未捕获的类型错误:无法读取未定义的属性“完成”

【问题讨论】:

你不能从done()返回任何东西。另请注意,您需要在内部函数中 return $.ajax(... 才能使 Promise 起作用。 我能做些什么呢?我试图连接所有三个功能,所以他们一个接一个地执行 可能是浏览器报错表达式().done 【参考方案1】:

您正在描述一系列链式异步操作。 Promise 非常适合这种情况。您从ajax 获得的Deferred 对象是一个承诺(现在),因此您可以通过返回从每个函数到下一个函数的链来实现:

$.ajax(
    // ...
)
.then(billingArray => billingArray[0]['total_count']) // *** Return the count
.then(totalProfiles => $.ajax( // *** Return the promise for the billing profiles
     // ...options using `totalProfiles`...
)
.then(billingProfiles => 
    // ...use the billing profiles here
)
.catch(() => 
    // ...handle/report failure
);

请注意每个then 处理程序如何转换通过它的内容,并且在它需要只能异步获得的信息的情况下,它会从ajax 返回承诺;结果将传递给下一个then 处理程序。

【讨论】:

谢谢!这已被证明是最简单、最好的解决方案【参考方案2】:

这会让你更接近:

const billingSelect = document.getElementById('billingSelect');

// This is an IIFE that gets executed immediately on page load

(function()
    $.ajax(
        url: url,
        method: 'GET',
        crossDomain: true,
        withCredentials: true,
        dataType: 'JSON',
        headers: 
            'Authorization': 'Basic '+token,
        
    )

  // call your function in the done handler, and pass the data in

    .done(response => 
       build(billingprofiles: response, totalProfiles: response['total_count']))
    .fail(function(jqXHR, textStatus, errorThrown)  console.log(textStatus); );
);

// your function gets called from the .done handler
// with the data it needs

function build(billingprofiles, totalProfiles) 

    // use const everywhere. You rarely need variables.
    // use map to transform the data to get the shape you need

    // console.log(billingprofiles) // uncomment to check the shape

    const profiles = billingprofiles.map(profile => (
        id: profile["ngcp:billingprofiles"]["id"],
        name: profile["ngcp:billingprofiles"]["name"]
    ))

   // console.log(profiles) // uncomment to check the shape

   // Use forEach when you need a side-effect, like DOM element creation
   // but only for that. For data transform, use map, filter and reduce.

   profiles.forEach(profile => 
     const opt = document.createElement("option");
     opt.value() = profile.id;
     opt.textContent() = profile.name;
     dropdown.appendChild(opt);
   )

【讨论】:

我马上去试试,谢谢你的快速回答!

以上是关于返回 GET 值并将其存储在 JS 中的变量中的主要内容,如果未能解决你的问题,请参考以下文章

如何计算数组中的相同值并将其存储到变量中?

将获取的值分配给 laravel 控制器中的变量

从数据库中检索值并将其存储为会话变量

如何将输入作为元组并将其存储在 Erlang 的变量中?

无法从不同的文件定义导入的对象,将其存储在一个状态中并将其传播到 React 中的另一个变量中

如何等待module.export函数完成请求,然后再将其返回值分配给不同JS文件中的变量[重复]