Поддержка  •  Дневник  •  Без рекламы  •  О сайте  •  Реклама  •  Поставить баннер  •  Fleshlight  •  Прислать  •  Хроника  •  Translate Гости: 3    Участники: 0 Авторизация Авторизация   Регистрация 
Метод Научного Тыка
RULVEN
Поиск  
Blackball iMag | интернет-журнал
Каталог


Начало » Разработка ПО » Асинхронный JavaScript: изучаем Async/Await, Callbacks и Promises
Мне повезёт!

Асинхронный JavaScript: изучаем Async/Await, Callbacks и Promises


Асинхронный JavaScript: изучаем Async/Await, Callbacks и Promises
Добавлено: Пн 15.05.2023 • Sergeant
Автор: Рафаил Агазода
Источник: источник
Просмотров: 839
Комментарии: 0


Сегодня мы попытаемся построить и запустить магазин мороженого, при этом одновременно изучить асинхронный JavaScript. Также вы узнаете, как использовать:

  1. Callbacks.
  2. Promises.
  3. Async / Await.

Вот что мы рассмотрим в этой статье:

  1. Что такое асинхронный JavaScript.
  2. Синхронный и асинхронный JavaScript.
  3. Как работают Callbacks в JavaScript.
  4. Как работают Promises в JavaScript.
  5. Как работает Async / Await в JavaScript.

Это — перевод оригинальной статьи на freeCodeCamp от автора Joy Shaheb.

Что такое асинхронный JavaScript

Если вы хотите разрабатывать эффективные проекты, то эта концепция идеально подходит вам.

Теория асинхронного JavaScript помогает разбивать большие сложные проекты на более мелкие задачи.

Вы можете использовать любую из этих трех техник — Callbacks, Promises или Async/await — для выполнения небольших задач таким образом, чтобы получить наилучшие результаты.

Синхронный и асинхронный JavaScript

Что такое синхронная система

В синхронной системе задачи выполняются одна за другой.

Представьте, что у вас всего одна рука для выполнения 10 задач. Из-за этого вы должны выполнять по одной задаче за один раз. По умолчанию JavaScript является синхронным или однопоточным. Подумайте об этом так: один поток означает одну руку, которой можно что-то делать.

Что такое асинхронная система

В этой системе задачи выполняются независимо друг от друга.

Представьте, что для выполнения 10 задач у вас есть 10 рук. Таким образом, каждая рука может выполнять задачу независимо друг от друга и одновременно.

Итак, в чём разница между синхронным и асинхронным JS

В синхронной системе изображения находятся в одном потоке обработки. Одно изображение не может обогнать другое. Загрузка завершается по очереди. Если первое изображение заканчивает загрузку, останавливается и следующее изображение.

В асинхронной системе изображения находятся на разных дорожках. Они закончат загрузку в своем собственном темпе. Никто ни перед кем не останавливается, если вдруг возникнет ошибка.

Примеры синхронного и асинхронного кода

Прежде чем начать наш проект, давайте рассмотрим несколько примеров.

Пример синхронного кода

Чтобы протестировать синхронную систему, напишите этот код на JavaScript:

console.log(" I ");
console.log(" eat ");
console.log(" Ice Cream ");

Вот результат в консоли:

Пример асинхронного кода

Допустим, чтобы съесть мороженое, требуется две секунды. Теперь давайте протестируем асинхронную систему. Напишите приведенный ниже код на JavaScript.

console.log("I");

// This will be shown after 2 seconds

setTimeout(()=>{
  console.log("eat");
}, 2000);

console.log("Ice Cream");

Примечание: Не волнуйтесь, функцию setTimeout() мы обсудим позже.

И вот результат в консоли:

Теперь, когда вы знаете разницу между синхронными и асинхронными операциями, давайте создадим наш магазин мороженого.

Как настроить наш проект

Для этого проекта вы можете просто открыть Codepen.io и начать кодить. Или вы можете сделать это в VS code или другом редакторе по вашему выбору.

Откройте раздел JavaScript, а затем откройте консоль разработчика. Мы напишем наш код и посмотрим результаты в консоли.

Что такое обратные вызовы в JavaScript

Когда вы вкладываете функцию в другую функцию в качестве аргумента, это называется обратным вызовом или callback.

Вот иллюстрация обратного вызова:

Не волнуйтесь, через минуту мы увидим несколько примеров обратных вызовов.

Зачем использовать обратные вызовы

При выполнении сложной задачи мы разбиваем ее на более мелкие шаги. Чтобы установить связь между этими шагами по времени (необязательно) и порядку, мы используем обратные вызовы.

Взгляните на этот пример:

Вот те небольшие шаги, которые необходимо сделать, чтобы приготовить мороженое.

Также обратите внимание, что в этом примере порядок действий и время имеют решающее значение. Вы не можете просто нарезать фрукты и подать мороженое.

В то же время, если предыдущий шаг не завершен, мы не можем перейти к следующему.

Магазин будет состоять из двух частей:

  1. В кладовой будут храниться все ингредиенты [Бэкенд].
  2. Производить мороженое мы будем на нашей кухне [Фронтенд].

Создаём и сохраняем данные

Теперь давайте создадим наши ингредиенты, то есть фрукты, внутри объекта.

let stocks = {
   Fruits : ["strawberry", "grapes", "banana", "apple"]
}

Дополним наши ингредиенты вафельными стаканчиками, топпингами и прочим:

let stocks = {
   Fruits : ["strawberry", "grapes", "banana", "apple"],
   liquid : ["water", "ice"],
   holder : ["cone", "cup", "stick"],
   toppings : ["chocolate", "peanuts"],
};

Весь бизнес зависит от того, что заказывает клиент. Как только мы получаем заказ, мы начинаем производство, а затем подаем мороженое. Итак, мы создадим две функции:

  1. order.
  2. production.

Вот как все это работает:


Получаем заказ, выбираем ингредиенты, готовим заказ и отдаём его.

Давайте создадим наши функции. Здесь мы будем использовать стрелочные функции:

let order = () => {};
let production = () => {};

Теперь давайте установим связь между этими двумя функциями с помощью обратного вызова, например, так:

let order = (call_production) => {
  call_production();
};

let production = () => {};

Давайте проведем небольшой тест

Мы будем использовать функцию console.log() для проведения тестов, чтобы развеять все сомнения, которые могут возникнуть относительно того, как мы установили связь между двумя функциями.

let order = (call_production) => {
console.log("Order placed. Please call production")
// function ???? is being called
    call_production();
};

let production = () => {
    console.log("Production has started")
};

Чтобы запустить тест, мы вызовем функцию order. И добавим в качестве аргумента вторую функцию с именем production.

Вот результат в нашей консоли:

 

Сохраните этот код и удалите все, но не удаляйте нашу переменную stocks.

В первой функции передайте еще один аргумент, чтобы мы могли получить заказ с названием нужного фрукта:

// Function 1

let order = (fruit_name, call_production) => {
  call_production();
};

// Function 2

let production = () => {};

// Trigger ????

order("", production);

Обозначим последовательность шагов и нужное время для их выполнения.

На этой схеме видно, что шаг 1 — размещение заказа, который занимает 2 секунды. Затем шаг 2 — нарезать фрукты (2 секунды), шаг 3 — добавить воду и лед (1 секунда), шаг 4 — запустить машину (1 секунда), шаг 5 — выбрать контейнер (2 секунды), шаг 6 — выбрать начинку (3 секунды) и шаг 7 — подать мороженое, что занимает 2 секунды.

Для определения нужного времени отлично подходит функция setTimeout(), так как она использует callback, принимая функцию в качестве аргумента.

Теперь давайте выберем наши фрукты и воспользуемся этой функцией:

// 1st Function

let order = (fruit_name, call_production) => {
  setTimeout(function(){
    console.log(`${stocks.Fruits[fruit_name]} was selected`)

// Order placed. Call production to start
   call_production();
  }, 2000)
};

// 2nd Function

let production = () => {
  // blank for now
};

// Trigger ????
order(0, production);

Вот результат в консоли. Обратите внимание, что результат отображается через 2 секунды.

Если вам интересно, как мы выбрали именно клубнику, вот код с форматом:

Ничего не удаляйте. Теперь мы начнем писать функцию для производства мороженого. Мы опять будем использовать стрелочные функции:

let production = () => {
  setTimeout(() => {
    console.log("production has started")
  },0000)
};

Результат:

Добавим еще одну функцию в setTimeout, чтобы нарезать фрукты.

let production = () => {

  setTimeout(()=> {
    console.log("production has started")

    setTimeout(()=> {
      console.log("The fruit has been chopped")
    },2000)

  },0000)
};

Результат:

Давайте завершим полный процесс производства мороженого, вложив новые функции внутрь существующих функций — это и есть обратный вызов, помните?

let production = () => {

  setTimeout(() => {
    console.log("production has started")
    setTimeout(() => {
      console.log("The fruit has been chopped")
      setTimeout(() => {
        console.log(`${stocks.liquid[0]} and ${stocks.liquid[1]} Added`)
        setTimeout(() => {
          console.log("start the machine")
          setTimeout(() => {
            console.log(`Ice cream placed on ${stocks.holder[1]}`)
            setTimeout(() => {
              console.log(`${stocks.toppings[0]} as toppings`)
              setTimeout(() => {
                console.log("serve Ice cream")
              },2000)
            },3000)
          },2000)
        },1000)
      },1000)
    },2000)
  },0000)

};

Смущены тем, как всё выглядит? Это ад обратных вызовов. 🙂 Они всегда выглядят примерно вот так:

Как же сделать так, чтобы код выглядел красивым?

Как использовать Promises, чтобы избежать ада обратного вызова

Promises были изобретены для избавления от ада обратных вызовов и для лучшей обработки наших задач.

Вот, как они выглядят:

Разберём, как они работают.

Как показано на графиках выше, promise имеет три состояния:

  1. Ожидание. Это начальная стадия. Здесь ничего не происходит. Подумайте об этом так: ваш клиент не торопится делать заказ. Он ещё ничего не заказал.
  2. Решено. Это означает, что ваш клиент получил свою еду и доволен.
  3. Отклонено. Это означает, что ваш клиент не получил свой заказ и покинул ресторан.

Давайте применим обещания в нашем примере с производством мороженого.

Сначала нам нужно понять еще четыре вещи:

  1. Взаимосвязь между временем и работой.
  2. Как работает цепочка Promise.
  3. Как работает обработка ошибок.
  4. Как работает обработчик .finally

Разберем каждую из этих концепций по очереди, делая небольшие шаги.

Взаимосвязь между временем и работой

Если вы помните, это наши шаги и время, которое занимает каждый шаг, чтобы сделать мороженое.

Чтобы это произошло, давайте создадим переменную в JavaScript:

let is_shop_open = true;

Теперь создайте функцию с именем order и передайте ей два аргумента с именами time, work:

let order = (time, work) => {

}

Теперь мы дадим обещание (Promise) нашему клиенту: «Мы подадим вам мороженое»:

let order = ( time, work ) => {
    return new Promise((resolve, reject) => { } )
}

Наше обещание состоит из 2 частей:

  1. Решено [мороженое доставлено].
  2. Отклонено [клиент не получил мороженое].

То есть Promise состоит из Resolve и Reject.

let order = (time, work) => {

  return new Promise((resolve, reject) => {

    if ( is_shop_open ) {
      resolve();
    }
    else {
      reject(console.log("Our shop is closed"));
    }
  })
}

Давайте добавим коэффициенты времени и работы внутри нашего promise с помощью функции setTimeout() внутри оператора if.

Примечание: В реальной жизни вы можете обойтись и без фактора времени. Это зависит от требований проекта.

let order = (time, work) => {
  return new Promise((resolve, reject) => {
    if (is_shop_open) {
      setTimeout(() => {
       // work is ???? getting done here
        resolve(work());

       // Setting ???? time here for 1 work
       }, time)
    }
    else {
      reject(console.log("Our shop is closed"));
    }
  })
}

Теперь мы используем нашу только что созданную функцию для запуска производства.

// Set ???? time here
order(2000, () => console.log(`${stocks.Fruits[0]} was selected`));
// pass a ☝️ function here to start working

Результат после двух секунд ожидания:

Цепочки обещаний

В этом методе мы определяем, что нам нужно сделать, когда первая задача будет выполнена, используя обработчик .then.


Обработчик .then возвращает promise, когда наше первое обещание будет разрешено.

Такой механизм похож на то, как вы даете кому-то инструкции. Вы говорите кому-то: «Сначала сделай это, потом сделай то, потом другое, потом…, потом…, потом…», и так далее.

  1. Первая задача — это первоначальный Promise.
  2. Остальные задачи возвращают наше обещание после того, как будет выполнена одна небольшая часть работы.

Давайте реализуем это в нашем проекте.

Примечание: не забудьте написать слово return внутри обработчика .then. В противном случае он не будет работать должным образом. Если вам интересно, зачем он нужен, попробуйте удалить return, когда мы закончим все шаги:

order(2000, () => console.log(`${stocks.Fruits[0]} was selected`));

.then(() => {
  return order(0000, () => console.log('production has started'));
})

Вот результат:

Используя ту же систему, закончим наш проект.

// step 1
order(2000, () => console.log(`${stocks.Fruits[0]} was selected`))

// step 2
.then(() => {
  return order(0000, () => console.log('production has started'))
})

// step 3
.then(() => {
  return order(2000, () => console.log("Fruit has been chopped"))
})

// step 4
.then(() => {
  return order(1000, () => console.log(`${stocks.liquid[0]} and ${stocks.liquid[1]} added`))
})

// step 5
.then(() => {
  return order(1000, () => console.log("start the machine"))
})

// step 6
.then(() => {
  return order(2000, () => console.log(`ice cream placed on ${stocks.holder[1]}`))
})

// step 7
.then(() => {
  return order(3000, () => console.log(`${stocks.toppings[0]} as toppings`))
})

// Step 8
.then(() => {
  return order(2000, () => console.log("Serve Ice Cream"))
})

Результат:

Обработка ошибок

Нам нужен способ обработки ошибок, когда что-то идет не так. Чтобы отловить ошибки, давайте изменим нашу переменную на false.

let is_shop_open = false;

Это означает, что наш магазин закрыт. Мы больше не продаем мороженое нашим клиентам.

Чтобы справиться с ошибкой, мы используем обработчик .catch. Как и .then, он также возвращает Promise, но только в том случае, если наше первоначальное обещание отклонено.

Итак, напоминаем:

  1. .then работает, когда Promise сработал как следует.
  2. .catch работает, когда Promise отвергнут.

Таким образом, между предыдущим обработчиком .then и обработчиком .catch не должно быть вообще ничего.

.catch(() => {
  console.log("Customer left")
})

Результат:

Что значит вывод после исполнения кода:

  1. Первое сообщение приходит от части reject() нашего Promise.
  2. Второе сообщение приходит из обработчика .catch.

Как использовать обработчик .finally()

Существует обработчик finally, который работает независимо от того, был ли наш Promise выполнен или отклонен.

Например: независимо от того, обслужили ли мы хотя бы одного клиента или 100 клиентов, наш магазин закроется в конце дня.

Вот пример такого кода:

.finally(() => {
  console.log("end of day")
})

Результат:

Как работает Async / Await в JavaScript

Предполагается, что это лучший способ написания Promise, который помогает нам сохранять код простым и чистым.

Все, что вам нужно сделать, это написать слово async перед любой обычной функцией, и она станет обещанием.

Promises против Async/Await на JavaScript

До появления async/await для выполнения обещания мы писали следующее:

function order() {
   return new Promise((resolve, reject) => {

    // Write code here
   } )
}

Теперь используем async:

// ???? the magical keyword
async function order() {
   // Write code here
}

Как использовать ключевые слова Try и Catch

Мы используем try для выполнения кода, а catch — для отлова ошибок. Это та же концепция, которую мы видели при рассмотрении обещаний.

Давайте сравним, как это работает.

В обещаниях мы использовали resolve и reject:

function kitchen() {

  return new Promise ((resolve, reject) => {
    if (true) {
       resolve("promise is fulfilled")
    }

    else {
        reject("error caught here")
    }
  })
}

kitchen()  // run the code
.then()    // next step
.then()    // next step
.catch()   // error caught here
.finally() // end of the promise [optional]

Когда мы используем async/await, мы используем этот формат:

// ???? Magical keyword
async function kitchen() {

   try {
// Let's create a fake problem
      await abc;
   }

   catch(error) {
      console.log("abc does not exist", error)
   }

   finally {
      console.log("Runs code anyways")
   }
}

kitchen()  // run the code

Теперь, надеемся, вы понимаете разницу между Promises и Async/Await.

Как использовать Await в JavaScript

Ключевое слово await заставляет JavaScript ждать, пока Promise выполнится и вернет результат.

Вернемся к нашему магазину мороженого. Мы не знаем, какой топпинг предпочтет покупатель: шоколад или арахис. Нам нужно остановить машину и спросить клиента, чего бы он хотел.

Заметьте, что мы остановили только кухню, но персонал вне кухни продолжает делать такие вещи, как:

  1. мытье посуды;
  2. уборка столов;
  3. приём заказов, и т.д.

Давайте создадим Promise, чтобы спросить, какой топпинг использовать. Процесс занимает три секунды.

function toppings_choice () {
  return new Promise((resolve, reject) => {
    setTimeout(() => {

      resolve( console.log("which topping would you love?") )

    }, 3000)
  })
}

Теперь давайте сначала создадим функцию для кухни с async.

async function kitchen(){

  console.log("A")
  console.log("B")
  console.log("C")

  await toppings_choice()

  console.log("D")
  console.log("E")

}

// Trigger the function

kitchen();

Давайте добавим другие задачи ниже kitchen().

console.log("doing the dishes")
console.log("cleaning the tables")
console.log("taking orders")

Вот результат:

Мы буквально выходим из кухни, чтобы спросить клиента: «Какой топпинг вы предпочитаете?». В это время другие задачи не заканчиваются.

Как только мы узнаем о выборе топпинга, мы возвращаемся на кухню и заканчиваем заказ.

При использовании Async/Await вы также можете использовать обработчики .then, .catch и .finally, которые являются основной частью Promises.

Запускаем магазин мороженого

Для этого создадим две функции:

  1. kitchen для приготовления мороженого;
  2. time для назначения количества времени, которое займет каждая небольшая задача.

Сначала создадим функцию time:

let is_shop_open = true;

function time(ms) {

   return new Promise((resolve, reject) => {

      if(is_shop_open) {
         setTimeout(resolve,ms);
      }

      else{
         reject(console.log("Shop is closed"))
      }
    });
}

Теперь создадим кухню:

async function kitchen() {
   try{
     // instruction here
   }

   catch(error) {
    // error management here
   }
}

// Trigger
kitchen();

Проверим, работает ли наша кухня:

async function kitchen() {
   try {

// time taken to perform this 1 task
     await time(2000)
     console.log(`${stocks.Fruits[0]} was selected`)
   }

   catch(error) {
     console.log("Customer left", error)
   }

   finally {
      console.log("Day ended, shop closed")
    }
}

// Trigger
kitchen();

Вот, что вы должны увидеть, если магазин считается открытым:

А вот, что будет, если магазин закрыт.

Завершим наш проект. Для этого вспомним, какие задачи должны выполняться в магазине:

Открываем магазин:

let is_shop_open = true;

Добавляем все функции для нашей кухни:

async function kitchen() {
    try {
  await time(2000)
  console.log(`${stocks.Fruits[0]} was selected`)

  await time(0000)
  console.log("production has started")

  await time(2000)
  console.log("fruit has been chopped")

  await time(1000)
  console.log(`${stocks.liquid[0]} and ${stocks.liquid[1]} added`)

  await time(1000)
  console.log("start the machine")

  await time(2000)
  console.log(`ice cream placed on ${stocks.holder[1]}`)

  await time(3000)
  console.log(`${stocks.toppings[0]} as toppings`)

  await time(2000)
  console.log("Serve Ice Cream")
    }

    catch(error){
   console.log("customer left")
    }
}

Результат:

Заключение

Поздравляем, вы дочитали до конца! В этой статье вы изучили:

  1. Разницу между синхронными и асинхронными системами.
  2. Механизмы асинхронного JavaScript с использованием обратных вызовов, обещаний и Async/Await.

Благодарим за то, что дочитали до конца!



Мне нравится 0   Мне не нравится 0



Комментарии

Чтобы добавить видео с YouTube, нужно написать [@youtube=xxxxx] , где xxxxx – ID видео.


Комментарии: 0
Нет ни одного комментария.
RSS-лента
Поделиться ссылкой:
Тестирование PRTG Network Monitor и сравнение с Zabbix Тестирование PRTG Network Monitor и сравнение с Zabbix
Рыба с картофелем в духовке: 9 рецептов Рыба с картофелем в духовке: 9 рецептов
Коктейль виски со Швепсом – оригинальные и согревающие рецепты Коктейль виски со Швепсом – оригинальные и согревающие рецепты
Блюда из говяжьей вырезки — 10 вкусных рецептов Блюда из говяжьей вырезки — 10 вкусных рецептов
10 удивительных древних театров 10 удивительных древних театров
Обзор смартфона Sony Xperia XZ2: новый рецепт японской кухни Обзор смартфона Sony Xperia XZ2: новый рецепт японской кухни
HDMI или Display Port: в чëм разница, и чем лучше выводить изображение на монитор HDMI или Display Port: в чëм разница, и чем лучше выводить изображение на монитор
Образцовый кинотеатр Dolby Atmos Образцовый кинотеатр Dolby Atmos
Смартфоны с разрешением лучше, чем у iPhone 4: прорыв или обман?
Sony Ericsson XPERIA Arc: первый взгляд Sony Ericsson XPERIA Arc: первый взгляд

javascript
300+ вопросов по JavaScript на собеседовании Пн 29.04.2024
300+ вопросов по JavaScript на собеседовании
30 вопросов на собеседовании фронтенд разработчика Пн 15.04.2024
30 вопросов на собеседовании фронтенд разработчика
Вт 02.04.2024
Вопросы и ответы для собеседования на позицию frontend-разработчик. Часть 2
Вт 02.04.2024
Вопросы и ответы для собеседования на позицию frontend-разработчик. Часть 1
DOM Enlightenment Вт 13.02.2024
DOM Enlightenment
Год: 2013
10 продвинутых способов писать в консоль помимо console.log Пн 29.05.2023
10 продвинутых способов писать в консоль помимо console.log
Асинхронный JavaScript: изучаем Async/Await, Callbacks и Promises Пн 15.05.2023
Асинхронный JavaScript: изучаем Async/Await, Callbacks и Promises
Learning React Чт 20.04.2023
Learning React
Год: 2020
JavaScript Everywhere Вт 18.04.2023
JavaScript Everywhere
Год: 2020
Fullstack React with TypeScript Чт 13.04.2023
Fullstack React with TypeScript
Год: 2020
Fullstack React Вт 11.04.2023
Fullstack React
Год: 2020
React and React Native, 3rd Edition Чт 06.04.2023
React and React Native, 3rd Edition
Год: 2020
Full-Stack React Projects, 2nd Edition Вт 04.04.2023
Full-Stack React Projects, 2nd Edition
Год: 2020
Пн 03.04.2023
Angular без CLI (руководство)
The Road to React Чт 30.03.2023
The Road to React
Год: 2020
React Hooks in Action Чт 23.03.2023
React Hooks in Action
Год: 2021
Learning PHP, MySQL & JavaScript Вт 21.03.2023
Learning PHP, MySQL & JavaScript
Год: 2018
Бессерверные приложения на JavaScript Вт 07.02.2023
Бессерверные приложения на JavaScript
Год: 2020
Programming JavaScript Applications Чт 05.01.2023
Programming JavaScript Applications
Год: 2014
Composing Software Вт 11.10.2022
Composing Software
Год: 2019
Data Structures and Algorithms with JavaScript Чт 06.10.2022
Data Structures and Algorithms with JavaScript
Год: 2014
Programming HTML5 Applications Вт 04.10.2022
Programming HTML5 Applications
Год: 2011
Создаем динамические веб-сайты с помощью PHP, MySQL, JavaScript, CSS и HTML5 Чт 26.05.2022
Создаем динамические веб-сайты с помощью PHP, MySQL, JavaScript, CSS и HTML5
Год: 2016
You Don't Know JS: Types & Grammar Вт 10.05.2022
You Don't Know JS: Types & Grammar
Год: 2015
You Don't Know JS: ES6 & Beyond Чт 05.05.2022
You Don't Know JS: ES6 & Beyond
Год: 2015
You Don't Know JS: Async & Performance Вт 03.05.2022
You Don't Know JS: Async & Performance
Год: 2015
You Don't Know JS: Up & Going Чт 28.04.2022
You Don't Know JS: Up & Going
Год: 2015
You Don't Know JS: this & Object Prototypes Вт 26.04.2022
You Don't Know JS: this & Object Prototypes
Год: 2014
You Don't Know JS: Scope & Closures Чт 21.04.2022
You Don't Know JS: Scope & Closures
Год: 2014
TypeScript: Modern JavaScript Development Чт 14.10.2021
TypeScript: Modern JavaScript Development
Год: 2016
Pro JavaScript Design Patterns Чт 16.09.2021
Pro JavaScript Design Patterns
Год: 2008
Mastering JavaScript Design Patterns Чт 24.06.2021
Mastering JavaScript Design Patterns
Год: 2014
JavaScript Patterns Вт 18.05.2021
JavaScript Patterns
Год: 2010
Learning JavaScript Design Patterns Чт 08.04.2021
Learning JavaScript Design Patterns
Год: 2012
Пн 05.04.2021
Замыкания в JavaScript для начинающих
Get Programming with JavaScript Вт 03.03.2020
Get Programming with JavaScript
Год: 2016
JavaScript Application Design Вт 25.02.2020
JavaScript Application Design
Год: 2015
Effective JavaScript: 68 Specific Ways to Harness the Power of JavaScript Вт 20.08.2019
Effective JavaScript: 68 Specific Ways to Harness the Power of JavaScript
Год: 2012
JavaScript. Шаблоны Вт 13.08.2019
JavaScript. Шаблоны
Год: 2011
Secrets of the JavaScript Ninja Вт 06.08.2019
Secrets of the JavaScript Ninja
Год: 2012
Eloquent JavaScript, 3rd Edition Вт 30.07.2019
Eloquent JavaScript, 3rd Edition
Год: 2018
Speaking JavaScript Вт 07.05.2019
Speaking JavaScript
Год: 2014
High Performance JavaScript Вт 23.04.2019
High Performance JavaScript
Год: 2010
Сила JavaScript Вт 16.04.2019
Сила JavaScript
Год: 2013
Functional Programming in JavaScript Вт 02.04.2019
Functional Programming in JavaScript
Год: 2015
Книги
Designing Data-Intensive Applications Вт 14.05.2024
Designing Data-Intensive Applications
Год: 2017
Fundamentals of Software Architecture Вт 07.05.2024
Fundamentals of Software Architecture
Год: 2020
Refactoring with C# Вт 23.04.2024
Refactoring with C#
Год: 2023

Разработано на основе BlackNight CMS
Release v.2024-05-25
© 2000–2024 Blackball
Дизайн & программирование:
О сайтеРеклама
Visitors
Web-site performed by Sergey Drozdov
BlackballРекламаСтатистикаПоддержка | МузыкаПлейлистыКиноВидеоИгрыАудиоПрограммыСтатьиКартинкиЮморФорумДневник сайтаПрислать контент