使用AJAX的JavaScript承诺

我试图将一系列AJAX请求写入字典.
我试图使用promises,但是我要么正确地编写promise语法,要么我认为可能发生的是函数实际完成(for循环已完成,AJAX请求已发送)但AJAX请求仍然存在没有回来.因此,这仍然是一个空字典.

let dict = {};
let activeMachines = ["41", "42", "43"];
let dataPromise = new Promise (function (resolve, reject){
  for(let i = 0; i < activeMachines.length; i++){
  let machineID = activeMachines[i]
  let getAPIData = new XMLHttpRequest();
  let url = 'http://127.0.0.1:8000/processes/apidata/' +machineID + '/';
  getAPIData.open('GET', url);
  getAPIData.send();
  getAPIData.onload = function(){
    let APIData = JSON.parse(getAPIData.responseText);
    dict['machine_' + machineID] = APIData[0].author_id;
    dict['temp' + machineID] = APIData[0].tempData; //get value
    dict['humid' + machineID] = APIData[0].humidData;
    timeValue = String((APIData[0].dateTime));
    dict['time' + machineID] = new Date(timeValue);
    console.log("done");
  }
}
resolve();
});

dataPromise.then(function() {
  console.log(dict);
});

当所有XMLHTTPRequests都返回时,有没有办法“感知”?

解决方法:

@Rafael的答案会起作用,但它并没有说明出错的原因,因为你试图理解Promises的概念并自己写一个.

从根本上说,我认为你的方法有两个失误:1.创建一个Promise来处理对你所有任意“activeMachines”列表的调用,以及2.将你的resolve()调用放在错误的地方.

通常Promise看起来像这样:

const myPromise = new Promise(function(resolve, reject) {
  doSomeAsyncWork(function(result) {
    // Some kind of async call with a callback function or somesuch...
    resolve(result);
  });
}).then(data => {
  // Do something with the final result
  console.log(data);
});

您可以使用setTimeout()模拟某种任意异步工作:

const myPromise = new Promise(function(resolve, reject) {
  // Resolve with "Done!" after 5 seconds
  setTimeout(() => {
    resolve("Done!");
  }, 5000);
}).then(data => {
  console.log(data); // "Done!"
});

但是,您的原始代码将resolve()调用放在一个奇怪的地方,甚至不传递任何数据.它看起来有点像这样:

const myPromise = new Promise(function(resolve, reject) {
  // Resolve with "Done!" after 5 seconds
  setTimeout(() => {
    // Doing some work here instead of resolving...
  }, 5000);
  resolve();
}).then(data => {
  console.log(data); // This would be "undefined"
});

你正在做一个console.log(“完成”);在您的原始代码中实际上您应该在哪里解决(someData);!

你也试图在你的Promise的异步函数中做副作用,这真的很奇怪,与Promise的工作方式相反.承诺应该是关闭并执行其异步工作,然后使用结果数据解决 – 字面上使用.then()链.

此外,您不应在Promise内部进行多次异步调用,而应将其概括为可重用且仅封装单个网络请求.这样你可以触发多个异步Promises,等待它们全部解决,然后做一些事情.

const activeMachines = ["41", "42", "43"];

// Make a reusable function that returns a single Promise
function fetchAPI(num) {
  return new Promise(function(resolve, reject) {
    const getAPIData = new XMLHttpRequest();
    const url = "http://127.0.0.1:8000/processes/apidata/" + num + "/";
    getAPIData.open("GET", url);
    getAPIData.send();
    getAPIData.onload = function() {
      const APIData = JSON.parse(getAPIData.responseText);
      const resolveData = {};
      resolveData["machine_" + num] = APIData[0].author_id;
      resolveData["temp" + num] = APIData[0].tempData; //get value
      resolveData["humid" + num] = APIData[0].humidData;
      timeValue = String(APIData[0].dateTime);
      resolveData["time" + num] = new Date(timeValue);
      resolve(resolveData);
    };
  });
}

// Promise.all() will resolve once all Promises in its array have also resolved
Promise.all(
  activeMachines.map(ea => {
    return fetchAPI(ea);
  })
).then(data => {
  // All of your network Promises have completed!
  // The value of "data" here will be an array of all your network results
});

fetch()API很棒,你也应该学会使用它 – 但只有在你理解了Promise实际操作背后的理论和实践之后.

相关文章

IE6是一个非常老旧的网页浏览器,虽然现在很少人再使用它,但...
PHP中的count()函数是用来计算数组或容器中元素的个数。这个...
使用 AJAX(Asynchronous JavaScript and XML)技术可以在不...
Ajax(Asynchronous JavaScript and XML)是一种用于改进网页...
本文将介绍如何通过AJAX下载Excel文件流。通过AJAX,我们可以...
Ajax是一种用于客户端和服务器之间的异步通信技术。通过Ajax...