• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Javascript problem z programowaniem sieci. Asynchroniczność

Object Storage Arubacloud
0 głosów
323 wizyt
pytanie zadane 29 maja 2023 w JavaScript przez andrzej.polak Nowicjusz (220 p.)
 const connections = [
    "Wieża kościelna-Boisko", "Wieża kościelna-Duży klon", "Duży klon-Boisko",
    "Duży klon-Las", "Duży klon-Ogród Fabienne", "Ogród Fabienne-Las",
    "Ogród Fabienne-Pastwisko", "Pastwisko-Duży dąb", "Duży dąb-Rzeźnia",
    "Rzeźnia-Wysoka topola", "Wysoka topola-Boisko", "Wysoka topola-Pałac",
    "Pałac-Duża sosna", "Duża sosna-Gospodarstw Jacques'a", "Gospodarstw Jacques'a-Głóg",
    "Duża sosna-Głóg", "Głóg-Ogród Gillesa", "Duża sosna-Ogród Gillesa",
    "Ogród Gillesa-Duży dąb", "Ogród Gillesa-Rzeźnia", "Pałac-Rzeźnia"
  ]

  function storageFor(name) {
    let storage = Object.create(null)
    storage["schowki na jedzenie"] = ["schowek w dębie", "schowek na łące", "schowek pod żywopłotem"]
    storage["schowek w dębie"] = "Dziura na trzecią dużą gałęzią od dołu. Kilka kawałków chleba i trochę szyszek."
    storage["shcowek na łące"] = "Zakopany pod pokrzywami (strona południowa). Zdechły wąż."
    storage["schowek pod żywopłotem"] = "Środek żywopłotu w ogrodzie Gillesa. Oznaczony rozgałęzionym patykiem. Dwie butelki piwa."
    storage["wrogowie"] = ["Pies Jacques'a", "Rzeźnik", "Ta jednonoga kawka", "Chłopiec z wiatrówką"]
    if (name == "Wieża kościelna" || name == "Głóg" || name == "Pałac")
      storage["events on 2017-12-21"] = "Głęboki śnieg. Śmieci rzeźnika mogą się przewrócić. Przegoniliśmy kruki z Saint-Vulbas."
    let hash = 0
    for (let i = 0; i < name.length; i++) hash += name.charCodeAt(i)
    for (let y = 1985; y <= 2018; y++) {
      storage[`chicks in ${y}`] = hash % 6
      hash = Math.abs((hash << 2) ^ (hash + y))
    }
    if (name == "Duży dąb") storage.scalpel = "Ogród Gillesa"
    else if (name == "Ogród Gillesa") storage.scalpel = "Las"
    else if (name == "Woods") storage.scalpel = "Pałac"
    else if (name == "Pałac" || name == "Rzeźnia") storage.scalpel = "Rzeźnia"
    else storage.scalpel = "Duży dąb"
    for (let prop of Object.keys(storage)) storage[prop] = JSON.stringify(storage[prop])
    return storage
  }

  class Network {
    constructor(connections, storageFor) {
      let reachable = Object.create(null)
      for (let [from, to] of connections.map(conn => conn.split("-"))) {
        ;(reachable[from] || (reachable[from] = [])).push(to)
        ;(reachable[to] || (reachable[to] = [])).push(from)
      }
      this.nodes = Object.create(null)
      for (let name of Object.keys(reachable))
        this.nodes[name] = new Node(name, reachable[name], this, storageFor(name))
      this.types = Object.create(null)
    }

    defineRequestType(name, handler) {
      this.types[name] = handler
    }

    everywhere(f) {
      for (let node of Object.values(this.nodes)) f(node)
    }
  }

  const $storage = Symbol("storage"), $network = Symbol("network")

  function ser(value) {
    return value == null ? null : JSON.parse(JSON.stringify(value))
  }

  class Node {
    constructor(name, neighbors, network, storage) {
      this.name = name
      this.neighbors = neighbors
      this[$network] = network
      this.state = Object.create(null)
      this[$storage] = storage
    }

    send(to, type, message, callback) {
      let toNode = this[$network].nodes[to]
      if (!toNode || !this.neighbors.includes(to))
        return callback(new Error(`Nie ma dostępu do ${to} z ${this.name}`))
      let handler = this[$network].types[type]
      if (!handler)
        return callback(new Error("Nieznany typ żądania " + type))
      if (Math.random() > 0.03) setTimeout(() => {
        try {
          handler(toNode, ser(message), this.name, (error, response) => {
            setTimeout(() => callback(error, ser(response)), 10)
          })
        } catch(e) {
          callback(e)
        }
      }, 10 + Math.floor(Math.random() * 10))
    }

    readStorage(name, callback) {
      let value = this[$storage][name]
      setTimeout(() => callback(value && JSON.parse(value)), 20)
    }

    writeStorage(name, value, callback) {
      setTimeout(() => {
        this[$storage][name] = JSON.stringify(value)
        callback()
      }, 20)
    }
  }

  
  


  if (typeof __sandbox != "undefined") {
    __sandbox.handleDeps = false
    __sandbox.notify.onLoad = () => {
      // Sztuczka opóźniająca wszystkie funkcje aż wszystkie węzły
      // podziałają przez 500 ms, aby dać im szansę na
      // rozesłanie informacji po sieci.
      let waitFor = Date.now() + 500
      function wrapWaiting(f) {
        return function(...args) {
          let wait = waitFor - Date.now()
          if (wait <= 0) return f(...args)
          return new Promise(ok => setTimeout(ok, wait)).then(() => f(...args))
        }
      }
      for (let n of ["routeRequest", "findInStorage", "chicks"])
        window[n] = wrapWaiting(window[n])
    }
  }

  if (typeof window != "undefined") {
    window.require = name => {
      if (name != "./crow-tech") throw new Error("Gniazda wron mogą żądać tylko \"./crow-tech\"")
      return exports
    }
  } else if (typeof module != "undefined" && module.exports) {
    module.exports = exports
  }

let network = new Network(connections, storageFor)
export const bigOak = network.nodes["Duży dąb"]
export const topola = network.nodes["Wysoka topola"]
export const everywhere = network.everywhere.bind(network)
export const defineRequestType = network.defineRequestType.bind(network)
import { bigOak, defineRequestType, everywhere, topola} from './crow-tech.js';
class Timeout extends Error {}
function request(nest, target, type, content) {
    return new Promise((resolve, reject) => {
        let done = false;
        function attempt(n) {
            nest.send(target, type, content, (failed, value) => {
                done = true;
                if(failed) reject(failed);
                else resolve(value);
            });
            setTimeout(() => {
                if (done) return;
                else if (n < 3) attempt(n + 1);
                else reject(new Timeout("Czas minął."));
            }, 250);
        }
        attempt(1);
    })
}

function requestType(name, handler) {
    defineRequestType(name, (nest, content, source, callback) => {
        try {
            Promise.resolve(handler(nest, content, source))
            .then(response => callback(null, response), 
                failure => callback(failure));
        } catch (exception) {
            callback(exception);
        }
    });
}

requestType("connections", (nest, {name, neighbors}, source) => {
    let connections = nest.state.connections;
    if(JSON.stringify(connections.get(name)) == JSON.stringify(neighbors)) return;
    connections.set(name, neighbors);
    broadcastConnections(nest, name, source);
});

function broadcastConnections(nest, name, exceptFor = null) {
    for(let neighbor of nest.neighbors) {
        if(neighbor == exceptFor) continue;
        request(nest, neighbor, "connections", {
            name,
            neighbors: nest.state.connections.get(name)
        });
    }
}
everywhere(nest => {
    nest.state.connections = new Map;
    nest.state.connections.set(nest.name, nest.neighbors);
    broadcastConnections(nest, nest.name);
})

function findRoute(from, to, connections) {
    let work = [{at: from, via: null}];
    for (let i = 0; i < work.length; i++) {
        let {at, via} = work[i];
        for(let next of connections.get(at) || []) {
            if(next == to) return via;
            if(!work.some(w => w.at == next)) {
                work.push({at: next, via: via || next});
            }
        }
    }
    return null;
}

function routeRequest(nest, target, type, content) {

    if(nest.neighbors.includes(target)) {
        
        return request(nest, target, type, content);
    } else {
        
        let via = findRoute(nest.name, target, nest.state.connections);
        if(!via) throw new Error(`No route to ${target}`);
        return request(nest, via, "route", {target, type, content});
    }
}
requestType("route", (nest, {target, type, content}) => {
    return routeRequest(nest, target, type, content);
}) 

Hej, chciałbym skorzystać z nowo napisanego typu żądania "route", ale niestety po wywołaniu 

bigOak.send("Pastwisko", "route", "test", response => console.log(response))

zwraca mi błąd "Error: No route to undefined" a więc jest tu jakiś problem z pobieraniem danych z nest. Jest to przykład z książki i po przepisaniu 1 w 1 oraz drobnych modyfikacjach nadal nie wiem jak poprawnie wywołać to żądanie. Czy ktoś może mi pomóc rozwiązać ten problem? Wiem że kod jest bardzo rozbudowany, ale próbowałem już wszystkich pomysłów 

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

0 głosów
1 odpowiedź 1,254 wizyt
0 głosów
3 odpowiedzi 416 wizyt
pytanie zadane 28 czerwca 2019 w JavaScript przez kordix Gaduła (3,910 p.)
0 głosów
1 odpowiedź 397 wizyt
pytanie zadane 19 stycznia 2021 w C i C++ przez Marak123 Stary wyjadacz (11,190 p.)

92,556 zapytań

141,403 odpowiedzi

319,559 komentarzy

61,942 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...