@ Ответ Рафаэля сработает, но он мало освещает происходящее, так как вы пытаетесь ухватить концепцию Обещаний и написать ее самостоятельно.
В принципе, я думаю, что ваш подход имеет два ошибочных шага: 1. создание одного Promise, который обрабатывает вызовы для всех ваших произвольных списков «activeMachines», и 2. размещение вашего вызова resolve()
в неправильном месте.
Обычно обещание выглядит так:
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("done");
в своем исходном коде, на самом деле вы должны делать resolve(someData);
!
Вы также пытаетесь выполнить побочный эффект внутри асинхронных функций вашего Promise, что действительно странно и противоречит принципам работы Promise. Обещание должно сработать и выполнить асинхронную работу, а , а затем разрешить с полученными данными - буквально с цепочкой .then()
.
Кроме того, вместо того, чтобы выполнять несколько асинхронных вызовов внутри вашего Promise, вы должны обобщить его, чтобы он мог использоваться повторно и инкапсулировал только один сетевой запрос. Таким образом, вы можете запустить несколько асинхронных Обещаний, подождать, пока они все разрешатся, и , а затем сделать что-то.
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
});
API fetch()
великолепен, и вы должны научиться использовать его также - но только после того, как вы поймете теорию и практику того, как на самом деле работают Promises. :)