123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587 |
- // Chat
- // Используя функцию jsonPost на адрес http://students.a-level.com.ua:10012 напишите чат-клиент, который:
- {// jsonPost function
- function jsonPost(url, data) {
- return new Promise((resolve, reject) => {
- var x = new XMLHttpRequest()
- x.onerror = () => reject(new Error('jsonPost failed'))
- x.open('POST', url, true)
- x.send(JSON.stringify(data))
- x.onreadystatechange = () => {
- if (x.readyState == XMLHttpRequest.DONE && x.status == 200) {
- resolve(JSON.parse(x.responseText))
- }
- else if (x.status != 200) {
- reject(new Error('status is not 200'))
- }
- }
- })
- }
- // общий div
- const allChat = document.createElement('div')
- allChat.style.cssText = `
- margin: 0 auto;
- width: min-content;
- padding: 10px;
- border: 1px solid #e5e5e5;
- border-radius: 10px;
- box-shadow: 5px 5px 10px 0px rgb(173 173 173);
- `
- document.body.append(allChat)
- // Stage 1 - работает нормаль, отслеживаем nextMessageId и записываем его в getMessageId
- const chatDiv = document.createElement('div')
- chatDiv.style.cssText = `
- border: 1px solid #e5e5e5;
- width: 550px;
- padding: 10px;
- margin-bottom: 20px;
- `
- allChat.append(chatDiv)
- const nickName = document.createElement('input')
- nickName.type = 'text'
- nickName.placeholder = 'Введите свой никнейм'
- nickName.value = 'Anon'
- chatDiv.append(nickName)
- let lineBreak = document.createElement('br')
- chatDiv.append(lineBreak)
- const inputText = document.createElement('textarea')
- inputText.maxlength = 500
- inputText.required
- inputText.style.cssText = `
- resize: none;
- margin: 20px 0px;
- height: 90px;
- width: 90%;
- `
- inputText.placeholder = 'Введите текст сообщения'
- inputText.value = 'Hi everyone!'
- chatDiv.append(inputText)
- lineBreak = document.createElement('br')
- chatDiv.append(lineBreak)
- const sendBtn = document.createElement('button')
- sendBtn.innerText = 'Send'
- sendBtn.style.padding = '3px 40px'
- chatDiv.append(sendBtn)
- // отправка сообщения по нажатию кнопки
- let getMessageId = 0
- sendBtn.onclick = () => {
- async function sendMessage() {
- const result = jsonPost('http://students.a-level.com.ua:10012', { func: 'addMessage', nick: `${nickName.value}`, message: inputText.value })
- await result.then(res => getMessageId = res.nextMessageId)
- console.log(getMessageId)
- return result.data
- }
- sendMessage()
- }
- // stage2
- {
- const chat = document.createElement('div')
- chat.style.cssText = `
- min-height: 500px;
- padding: 10px;
- height: 60%;
- width: 550px;
- overflow-y: scroll;
- overflow-x: hidden;
- `
- allChat.append(chat)
- async function getAllMessages() {
- const result = await jsonPost('http://students.a-level.com.ua:10012', { func: "getMessages", messageId: 0 })
- const chat = document.createElement('div')
- chat.style.cssText = `
- min-height: 500px;
- padding: 10px;
- height: 60%;
- width: 550px;
- overflow-y: scroll;
- overflow-x: hidden;
- `
- allChat.append(chat)
- for (const message of ((result.data).sort((a, b) => b.timestamp - a.timestamp))) {
- const chatBlock = document.createElement('div')
- chatBlock.style.cssText = `
- border: 1px solid #e5e5e5;
- border-radius: 10px;
- width: 500px;
- padding: 10px;
- margin-bottom: 20px;
- box-shadow: 5px 5px 10px 0px rgb(173 173 173);
- `
- chat.append(chatBlock)
- for (const [key, value] of Object.entries(message)) {
- const messageBlock = document.createElement('p')
- messageBlock.style.margin = '5px 0'
- messageBlock.innerHTML = `<span style = 'font-weight: 800;'>${key}</span>: ${typeof value === 'string' ? value : new Date(value)}`
- chatBlock.append(messageBlock)
- }
- }
- return result.data
- }
- getAllMessages()
- }
- // stage3
- let getNewMessageId = 0
- const chat = document.createElement('div')
- chat.style.cssText = `
- min-height: 500px;
- padding: 10px;
- height: 60%;
- width: 550px;
- overflow-y: scroll;
- overflow-x: hidden;
- `
- allChat.append(chat)
- async function getMessages(param) {
- const result = await jsonPost('http://students.a-level.com.ua:10012', { func: "getMessages", messageId: param })
- for (const message of result.data) {
- const chatBlock = document.createElement('div')
- chatBlock.style.cssText = `
- border: 1px solid #e5e5e5;
- border-radius: 10px;
- width: 500px;
- padding: 10px;
- margin-bottom: 20px;
- box-shadow: 5px 5px 10px 0px rgb(173 173 173);
- `
- chat.prepend(chatBlock)
- for (const [key, value] of Object.entries(message)) {
- const messageBlock = document.createElement('p')
- messageBlock.style.margin = '5px 0'
- messageBlock.innerHTML = `<span style = 'font-weight: 800;'>${key}</span>: ${typeof value === 'string' ? value : new Date(value)}`
- chatBlock.append(messageBlock)
- }
- }
- getNewMessageId = result.nextMessageId
- return result.data
- }
- getMessages(getNewMessageId)
- // stage 4
- const intervalId = setInterval(() => getMessages(getNewMessageId), 4000)
- // stage 5
- {
- function jsonPost(url, data) {
- return new Promise((resolve, reject) => {
- var x = new XMLHttpRequest()
- x.onerror = () => reject(new Error('jsonPost failed'))
- x.open('POST', url, true)
- x.send(JSON.stringify(data))
- x.onreadystatechange = () => {
- if (x.readyState == XMLHttpRequest.DONE && x.status == 200) {
- resolve(JSON.parse(x.responseText))
- }
- else if (x.status != 200) {
- reject(new Error('status is not 200'))
- }
- }
- })
- }
- // общий div
- const allChat = document.createElement('div')
- allChat.style.cssText = `
- margin: 0 auto;
- width: min-content;
- padding: 10px;
- border: 1px solid #e5e5e5;
- border-radius: 10px;
- box-shadow: 5px 5px 10px 0px rgb(173 173 173);
- `
- document.body.append(allChat)
- const chatDiv = document.createElement('div')
- chatDiv.style.cssText = `
- border: 1px solid #e5e5e5;
- width: 550px;
- padding: 10px;
- margin-bottom: 20px;
- `
- allChat.append(chatDiv)
- const nickName = document.createElement('input')
- nickName.type = 'text'
- nickName.placeholder = 'Введите свой никнейм'
- nickName.value = 'Anon'
- chatDiv.append(nickName)
- let lineBreak = document.createElement('br')
- chatDiv.append(lineBreak)
- const inputText = document.createElement('textarea')
- inputText.maxlength = 500
- inputText.required
- inputText.style.cssText = `
- resize: none;
- margin: 20px 0px;
- height: 90px;
- width: 90%;
- `
- inputText.placeholder = 'Введите текст сообщения'
- inputText.value = 'Hi everyone!'
- chatDiv.append(inputText)
- lineBreak = document.createElement('br')
- chatDiv.append(lineBreak)
- const sendBtn = document.createElement('button')
- sendBtn.innerText = 'Send'
- sendBtn.style.padding = '3px 40px'
- chatDiv.append(sendBtn)
- // отправка сообщения по нажатию кнопки
- let getMessageId = 0
- // async function sendMessage(nick, message) отсылает сообщение.
- async function sendMessage() {
- const result = jsonPost('http://students.a-level.com.ua:10012', { func: 'addMessage', nick: `${nickName.value}`, message: inputText.value })
- await result.then(res => getMessageId = res.nextMessageId)
- console.log(getMessageId)
- return result.data
- }
- // async function getMessages() получает сообщения и отрисовывает их в DOM
- const chat = document.createElement('div')
- chat.style.cssText = `
- min-height: 500px;
- padding: 10px;
- height: 60%;
- width: 550px;
- overflow-y: scroll;
- overflow-x: hidden;
- `
- allChat.append(chat)
- let getNewMessageId = 0
- async function getMessages(param) {
- const result = await jsonPost('http://students.a-level.com.ua:10012', { func: "getMessages", messageId: param })
- for (const message of result.data) {
- const chatBlock = document.createElement('div')
- chatBlock.style.cssText = `
- border: 1px solid #e5e5e5;
- border-radius: 10px;
- width: 500px;
- padding: 10px;
- margin-bottom: 20px;
- box-shadow: 5px 5px 10px 0px rgb(173 173 173);
- `
- chat.prepend(chatBlock)
- for (const [key, value] of Object.entries(message)) {
- const messageBlock = document.createElement('p')
- messageBlock.style.margin = '5px 0'
- messageBlock.innerHTML = `<span style = 'font-weight: 800;'>${key}</span>: ${typeof value === 'string' ? value : new Date(value)}`
- chatBlock.append(messageBlock)
- }
- }
- getNewMessageId = result.nextMessageId
- return result.data
- }
- getMessages(getNewMessageId)
- // async function sendAndCheck() использует две предыдущие для минимизации задержки между отправкой сообщения и приходом их.Именно эта функция должна запускаться по кнопке.
- async function sendAndCheck() {
- await Promise.all([sendMessage(), getMessages(getNewMessageId)])
- }
- sendBtn.onclick = () => sendAndCheck()
- // async function checkLoop() использует delay и бесконечный цикл для периодического запуска getMessages().
- async function checkLoop(param) {
- const delay = ms => new Promise(ok => setTimeout(() => ok(ms), ms))
- while (true) {
- await delay(param).then(() => getMessages(getNewMessageId))
- }
- }
- checkLoop(5000)
- }
- // stage 6
- // Заменить внутренности jsonPost на код, использующий fetch вместо XMLHttpRequest.
- {
- function jsonPost(url, data) {
- return new Promise((resolve, reject) => {
- fetch(url, { method: 'POST', body: JSON.stringify(data) })
- .then(res => res.json())
- .then(data => resolve(data), () => reject(new Error('status is not 200')))
- })
- }
- // общий div
- const allChat = document.createElement('div')
- allChat.style.cssText = `
- margin: 0 auto;
- width: min-content;
- padding: 10px;
- border: 1px solid #e5e5e5;
- border-radius: 10px;
- box-shadow: 5px 5px 10px 0px rgb(173 173 173);
- `
- document.body.append(allChat)
- const chatDiv = document.createElement('div')
- chatDiv.style.cssText = `
- border: 1px solid #e5e5e5;
- width: 550px;
- padding: 10px;
- margin-bottom: 20px;
- `
- allChat.append(chatDiv)
- const nickName = document.createElement('input')
- nickName.type = 'text'
- nickName.placeholder = 'Введите свой никнейм'
- nickName.value = 'Anon'
- chatDiv.append(nickName)
- let lineBreak = document.createElement('br')
- chatDiv.append(lineBreak)
- const inputText = document.createElement('textarea')
- inputText.maxlength = 500
- inputText.required
- inputText.style.cssText = `
- resize: none;
- margin: 20px 0px;
- height: 90px;
- width: 90%;
- `
- inputText.placeholder = 'Введите текст сообщения'
- inputText.value = 'Hi everyone!'
- chatDiv.append(inputText)
- lineBreak = document.createElement('br')
- chatDiv.append(lineBreak)
- const sendBtn = document.createElement('button')
- sendBtn.innerText = 'Send'
- sendBtn.style.padding = '3px 40px'
- chatDiv.append(sendBtn)
- // отправка сообщения по нажатию кнопки
- let getMessageId = 0
- // async function sendMessage(nick, message) отсылает сообщение.
- async function sendMessage() {
- const result = jsonPost('http://students.a-level.com.ua:10012', { func: 'addMessage', nick: `${nickName.value}`, message: inputText.value })
- await result.then(res => getMessageId = res.nextMessageId)
- console.log(getMessageId)
- return result.data
- }
- // async function getMessages() получает сообщения и отрисовывает их в DOM
- const chat = document.createElement('div')
- chat.style.cssText = `
- min-height: 500px;
- padding: 10px;
- height: 60%;
- width: 550px;
- overflow-y: scroll;
- overflow-x: hidden;
- `
- allChat.append(chat)
- let getNewMessageId = 0
- async function getMessages(param) {
- const result = await jsonPost('http://students.a-level.com.ua:10012', { func: "getMessages", messageId: param })
- for (const message of result.data) {
- const chatBlock = document.createElement('div')
- chatBlock.style.cssText = `
- border: 1px solid #e5e5e5;
- border-radius: 10px;
- width: 500px;
- padding: 10px;
- margin-bottom: 20px;
- box-shadow: 5px 5px 10px 0px rgb(173 173 173);
- `
- chat.prepend(chatBlock)
- for (const [key, value] of Object.entries(message)) {
- const messageBlock = document.createElement('p')
- messageBlock.style.margin = '5px 0'
- messageBlock.innerHTML = `<span style = 'font-weight: 800;'>${key}</span>: ${typeof value === 'string' ? value : new Date(value)}`
- chatBlock.append(messageBlock)
- }
- }
- getNewMessageId = result.nextMessageId
- return result.data
- }
- getMessages(getNewMessageId)
- // async function sendAndCheck() использует две предыдущие для минимизации задержки между отправкой сообщения и приходом их.Именно эта функция должна запускаться по кнопке.
- async function sendAndCheck() {
- await Promise.all([sendMessage(), getMessages(getNewMessageId)])
- }
- sendBtn.onclick = () => sendAndCheck()
- // async function checkLoop() использует delay и бесконечный цикл для периодического запуска getMessages().
- async function checkLoop(param) {
- const delay = ms => new Promise(ok => setTimeout(() => ok(ms), ms))
- while (true) {
- await delay(param).then(() => getMessages(getNewMessageId))
- }
- }
- checkLoop(5000)
- }
- }
- // SWAPI Links
- // Напишите промисифицированную функцию, которая будет принимать параметром ссылку на swapi.dev(например, https://swapi.dev/api/people/20) и скачивать всю информацию по ссылке, включая вложенные ссылки. Все ссылки внутри скачанного объекта должны заменяться на скачанные объекты. Полученный общий объект должен стать результатом промиса, который возвращает функция.
- {
- const swapiLinks = async (url) => {
- let result = {}
- let arrWithLinks = []
- let arrWithPromises = []
- const hero = await fetch(url)
- const heroData = await hero.json()
- for (const [key, values] of Object.entries(heroData)) {
- // сортируем массивы/ссылки/строки из fetch и складываем ссылки (обычные и из массивов) в новый массив
- if (Array.isArray(values)) {
- if (values.length > 0) {
- for (const value of values) {
- arrWithLinks.push({
- [key]: value,
- })
- }
- } else {
- result[key] = values
- }
- } else if (values.startsWith('https://swapi.dev/api/')) {
- arrWithLinks.push({
- [key]: values,
- })
- } else {
- result[key] = values
- }
- }
- // итерируем новый массив со ссылками, запускаем параллельный fetch для каждой ссылки
- for (const item of arrWithLinks) {
- for (const [keyToParse, urlToParse] of Object.entries(item)) {
- arrWithPromises.push(fetch(urlToParse)
- .then(res => res.json())
- .then(res => {
- let itemOfPromise = {
- [keyToParse]: res
- }
- return itemOfPromise
- }))
- }
- }
- // парсим все ссылки и возвращаем все в объект
- const resultsAll = Promise.all(arrWithPromises)
- .then(res => {
- // собираем все обратно в лоб
- let arrKeys = []
- let resultObj = {}
- // удаляем дубли повторяющихся ключей и пушим оригинальные в массив
- for (const item of res) {
- for (const key in item) {
- if (!(arrKeys.includes(key))) {
- arrKeys.push(key)
- }
- }
- }
- // собираем все в один объект с массивами в ключах
- for (const item of arrKeys) {
- resultObj[item] = []
- for (const itemObject of res) {
- for (const [key, value] of Object.entries(itemObject)) {
- if (key === item) {
- resultObj[item].push(value)
- }
- }
- }
- }
- Object.assign(result, resultObj)
- return result // расскомментировать, когда будет все готово. этот result отвечает за вывод всего в консоль
- })
- return resultsAll
- }
- swapiLinks("https://swapi.dev/api/people/20/")
- .then(res => console.log('FULL RESULT: ', JSON.stringify(res, null, 4)))
- }
- // domEventPromise
- // Реализуйте промисифицированную функцию, которая резолвит промис по событию в DOM:
- // Функция должна:
- // используя addEventListener повесить свой обработчик события на DOM element событие eventName
- // по событию зарезолвить промис отдав в качестве результата объект события
- // убрать обработчик с DOM - элемента, используя removeEventListener.
- {
- function domEventPromise(element, eventName) {
- function executor(resolve) {
- function event(param) {
- resolve(param)
- element.removeEventListener(eventName, event)
- }
- element.addEventListener(eventName, event)
- }
- return new Promise(executor)
- }
- const btn = document.createElement('button')
- btn.innerHTML = `click`
- document.body.append(btn)
- domEventPromise(btn, 'click').then(e => console.log('event click happens', e))
- }
|