使用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","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实际操作背后的理论和实践之后. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |