javascript, $.ajax, variable name

天大地大妈咪最大 提交于 2019-12-18 09:17:41

问题


I'm trying to iterate over an array and assign a variable with a for loop. So something like this:

function Person(name, status){
  this.name = name;
  this.status = status;
}

var status = [];
var array = ["bill","bob","carl","ton"];
function exAjax(function(){
 for(var i = 0; i < array.length; i++){
   var name = array[i];
   console.log(name); =====> this gives the correct name

   $.ajax({
     url: xxxxxxx,
     success: function(data){
       if(data.stream === null){
         var person = new Person(name, "dead");
         console.log(name); =====> return undefined until the last
         person

         status.push(person);       
       }
     }

   })
   name = "";
 }
})

The problem I'm having is that name is not getting into the success function. I thought js keeps traveling upwards to look for the variable if it doesn't exist in it's current scope? I'm getting undefined for the name variable if I try to console.log name! Scope masters what am I doing wrong?


回答1:


You can use .queue(), $.map() to maintain scope of name. Also, change status array to an object having property status where value is an array to prevent possible conflict with this.status of Person object.

Note, you can also chain .promise(/* queueName */) to perform tasks at .then() when all queued functions in queueName, i.e.g., "status" have been called, queueName .length is 0.

function Person(name, status){
  this.name = name;
  this.status = status;
}

var blob = new Blob(['{"stream":null}'], {type:"application/json"});
var url = URL.createObjectURL(blob);
// change `status` array reference, e.g., to `arr`
var arr = {status:[]};
var array = ["bill","bob","carl","ton"];

$(arr).queue("status", $.map(array, function(curr) {
  return function(next) {
    var name = curr;
    // do asynchronous stuff
    $.ajax({url:url, dataType:"json"})
    .then(function(data) {
       if(data.stream == null){
         var person = new Person(name, "dead");
         console.log(name, person);
         arr.status.push(person);
       }
    })
    .then(next) // call next function in `"status"` queue
  }
}))
.dequeue("status")
.promise("status")
// do stuff when all functions in `"status"` queue have completed,
// `"status"` queue `.length` is `0`
.then(function() {
   // `this` : `arr` as jQuery object
   // `this[0].status`: array containing objects pushed to `arr.status`
   console.log(this[0].status); // $(this).prop("status");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>

jsfiddle https://jsfiddle.net/nnayjckc/2/


You can alternatively use $.when(), .apply(), $.map(), to return same result

function Person(name, status) {
  this.name = name;
  this.status = status;
}

var blob = new Blob(['{"stream":null}'], {
  type: "application/json"
});
var url = URL.createObjectURL(blob);
// change `status` array reference, e.g., to `arr`
var arr = {
  status: []
};
var array = ["bill", "bob", "carl", "ton"];

$.when.apply($, $.map(array, function(curr) {
  var name = curr;
  return $.ajax({
      url: url,
      dataType: "json"
    })
    .then(function(data) {
      if (data.stream == null) {
        var person = new Person(name, "dead");
        console.log(name, person);
        arr.status.push(person);
      }
    })
}))
.then(function() {
  console.log(arr.status)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">  
</script>

jsfiddle https://jsfiddle.net/nnayjckc/3/




回答2:


That's because $.ajax perform an asynchronous HTTP (Ajax) request. It means that your for loop won't wait for success to complete. Instead it will continue with its iteration.

One way (of the many possible solutions), is to make this $.ajax synchronous with the async: false option

From the documentation

async (default: true)
Type: Boolean
By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option to false.

 for(var i = 0; i < array.length; i++){
   var name = array[i];
   console.log(name); =====> this gives the correct name

   $.ajax({
     url: xxxxxxx,
     async: false,
     success: function(data){
       if(data.stream === null){
         var person = new Person(name, "dead");
         console.log(name); =====> return undefined until the last
         person

         status.push(person);       
       }
     }

   })
   name = "";
 }
})


来源:https://stackoverflow.com/questions/38758499/javascript-ajax-variable-name

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!