#javascript #typescript #asynchronous #promise
#javascript #typescript #асинхронный #обещание
Вопрос:
У меня есть служба typescript, которая загружает базовые данные по htpp-запросам с сервера. Есть несколько запросов для нескольких данных, расположенных в порядке от независимых данных к данным в зависимости от данных, для которых загрузка была начата ранее. Из-за асинхронных http-запросов не гарантируется, что загрузка данных по запросу (например, клиенты в следующем примере) завершена, или начинается загрузка данных, которые зависят от него (например, устройства в следующем примере), и я не могу ссылаться на загружаемые устройства на загруженных клиентов. Но я хотел бы, чтобы обработка зависимых данных (устройств) начиналась после завершения загрузки данных, переданных (клиентам). Я думаю, мне нужно использовать promises, но как реализовать concrete в следующей ситуации с кодом?
export class BaseDataService
{
customers: Customer[] = new Array();
devices: Device[] = new Array();
// Loads the base data arranged in order from undependent data to data dependent data
loadBaseData() {
this.loadCustomers();
// this operation should be started after loading customers has finished (the response json
//is parsed to an array of customers at set to the instance variable of this service class)
this.loadDevices();
}
// Loads the customers and adds them to the collection of customers.
// Also puts the response json string of the customers to the local storage.
loadCustomers() {
console.log("Load customers");
var requestURL = 'https://myurl/kunden_json_user_extern.php';
var auth = window.localStorage.getItem('auth');
var requestparam = "auth=" auth;
var request = new XMLHttpRequest();
request.open('POST', requestURL);
request.setRequestHeader("content-type", "application/x-www-form-urlencoded");
request.send(requestparam);
request.onload = () => {
if (request.status === 200){
console.log("Load customers response");
// gets as json string with the customers array
var response = request.response;
// parses the json string of customers to an array of customers objects
this.customers = this.parseCustomers(response);
console.log("Load customers complete");
}
else if (request.status === 401){
alert("unautorized");
}
else {
// lade saved items aus local storage
alert("unerwarteter Fehler");
}
}
}
// Loads the devices and adds them to the collection of devices.
// Also puts the response json string of the devices to the local storage.
loadDevices() {
console.log("Load devices");
var requestURL = 'https://myurl/geraete_json_user_extern.php';
var auth = window.localStorage.getItem('auth');
var requestparam = "auth=" auth;
var request = new XMLHttpRequest();
request.open('POST', requestURL);
request.setRequestHeader("content-type", "application/x-www-form-urlencoded");
request.send(requestparam);
request.onload = () => {
if (request.status === 200){
console.log("Load devices response");
var response = request.response;
window.localStorage.setItem('devicesresponse', response);
this.devices = this.parseDevices(response);
console.log("Load devices complete");
}
else if (request.status === 401){
alert("unautorized");
}
else {
// lade saved items aus local storage
alert("unerwarteter Fehler");
}
}
}
// Parses a json string formatted like the response of customers to an array of customers
parseCustomers(customersjson: string)
{
let customerarray = JSON.parse(customersjson);
let customers: Customer[] = [];
for (let i = 0; i < customerarray.length; i ) {
let customer: Customer = new Customer();
customer.setId(customerarray[i]['id']);
customer.setName(customerarray[i]['name']);
customer.setPlace(customerarray[i]['ort']);
customer.setStreet(customerarray[i]['strasse']);
customers[i] = customer;
}
return customers;
}
// Parses a json string formatted like the response of devices to an array of devices
parseDevices(devicesjson: string)
{
let devicearray = JSON.parse(devicesjson);
let devices: Device[] = [];
for (let i = 0; i < devicearray.length; i ) {
let device = new Device();
device.setId(devicearray[i]['geraet_id']);
device.setSerialnumber(devicearray[i]['geraet_seriennummer']);
device.setDescription(devicearray[i]['geraet_bezeichnung']);
// here i would like to refer to a prevoiusly loaded customer
//device.setCustomer(this.baseDataService.getCustomer(devicearray[i]['geraet_kunde_id']);
device.setLocation(devicearray[i]['geraet_standort']);
devices[i] = device;
}
return devices;
}
}
Комментарии:
1. Почему бы не использовать что-то вроде axios, которое оборачивает это в обещание для вас?
2. Пожалуйста, прекратите использовать функции 20-летней давности. Вместо этого используйте выборку
3. Ответ на вашу проблему заключается в использовании async / await
4. Дайте мне знать, сработал ли мой ответ на синхронный вызов ajax!
Ответ №1:
Вы можете передать обратный вызов любой из функций ‘load’, чтобы:
Этот код:
loadBaseData() {
this.loadCustomers();
// this operation should be started after loading customers has finished (the response json
//is parsed to an array of customers at set to the instance variable of this service class)
this.loadDevices();
}
Измените этот код:
loadBaseData() {
this.loadCustomers(() => {
this.loadDevices();
});
}
И вызовите этот обратный вызов внутри вашего request.onload
:
// Loads the customers and adds them to the collection of customers.
// Also puts the response json string of the customers to the local storage.
loadCustomers(callback) { // <--- this is a callback passed to function
// ... many code here ...
request.onload = () => {
// ... many code here ...
console.log("Load customers complete");
if (typeof callback === 'function') callback(); // <--- here we call it
}
// ... many code here ...
Комментарии:
1. Я думаю, что передача обратного вызова не была бы хорошей. это всего лишь отрывок, и было бы загружено гораздо больше данных, передача обратного вызова функции загрузки, которой передается обратный вызов и так далее, Привела бы к аду вызовов.
2. выполнение синхронного вызова xhr.open(«»post, url, false) работает, спасибо
3. я знаю, что использование выборки и async / await было бы самым лучшим и современным решением. но я новичок в javascript и не понимаю использования promise. Как бы я должен был реализовать это с использованием promise и async / await
Ответ №2:
Вы можете выполнить synchronous ajax
вызов, подобный приведенному ниже. Таким образом, он ожидает ответа перед выполнением следующих инструкций.
xhr.open("POST",url,false);