Обратный вызовой ад
Для программистов JavaScript обработка обратных вызовов является домашней, но обработка обратных вызовов со слишком глубокими уровнями не так красиво. В следующем примере фрагмента кода используется трехслойные обратные вызовы, а затем пополняет мозг для большего количества слоев сцен. Это просто кислый. Это легендарный обратный вызов ад.
getDirectories (function (dirs) {getFiles (dirs [0], function (files) {getContent (files [0], function (file, content) {console.log ('filename:', file); console.log (content);});});}); function getDirectories (callback) {settimeout (function () {callback (['/home/ben']);}, 1000);} function getFiles (dir, callback) {settimeout (function () {callback ([dir + '/test1.txt', dir + '/test2.txt']);}, 1000)} stect -letcttent (file)}} stectcontent (file)}); setTimeout (function () {callback (file, 'content');}, 1000)}Решение
В экосистеме есть много асинхронных решений, которые могут решить проблему обратного ада, таких как синяя птица, Q и т. Д. Эта статья фокусируется на поддержке асинхронного программирования в спецификации ECMASCRPT 6/7.
ES6 обещание
Обещание - это решение для асинхронного программирования и мощного инструмента для решения проблемы ада обратного вызова.
Обещание было принято в экосистеме JavaScript в 2007 году, когда фреймворк Dojo добавила функциональность Dojo.deferred. С популярностью Dojo.Deferred, в 2009 году, Крис Зип предложил Sommonjs обещания/A спецификацию. Впоследствии в экосистеме появилось большое количество реализаций перспективных обещаний, включая Q.JS, FuburesJS и т. Д. Затем, как вы можете видеть, спецификация ES 6 включает в себя обещание.
Обещание описано в MDN следующим образом:
Объект обещания является прокси для возвращаемого значения, которое может быть неизвестно, когда создается объект обещания. Это позволяет вам указать метод обработки для успеха или сбоя асинхронной работы. Это позволяет асинхронному методу возвращать значение, подобное синхронному методу: асинхронный метод возвращает исходное возвращаемое значение
Следующий код является примером в разделе «Callback Hell», реализованного через обещание. Код не выглядит очень кратким, но он значительно улучшился по сравнению с традиционными иерархическими вызовами, и код более поддерживается и читается.
getDirectories (). Затем (function (dirs) {return getFiles (dirs [0]);}). Тогда (function (files) {return getContent (файлы [0]);}). Тогда (function (val) {console.log ('filename:', val.file); console.log (val.content);}); Function getDirectories () {return New Promise (function (Resolve, doject) {setTimeout (function () {Resolve (['/home/ben']);}, 1000);});} function getFiles (dir) {return new Promise (function, reject) {setTimeout (function () {reesolve (dir +'tstest1.txt1. '/test2.txt']);}, 1000);ES6 Генератор
Реализация обещания недостаточно проста, нам все еще нужен лучший выбор, и CO является одним из вариантов. CO является асинхронным контроллером потока на основе генератора. Прежде чем понимать CO, вам нужно сначала понять генератор. Студенты, которые знакомы с C#, должны понимать, что версия C# 2.0 представляет ключевое слово доходности для итерации генератора. Генератор ES 6 похож на C#, а также использует синтаксис урожайности сахара и реализует государственный компьютер внутри. Для конкретного использования, пожалуйста, обратитесь к разделу функции документа MDN и обратитесь к блогу команды AlloyTeam для глубокого понимания генератора. Используйте CO, чтобы умело объединить генератор ES6 и ES6 обещание сделать асинхронные вызовы более гармоничными.
co (function* () {var dirs = will getDirectories (); var files = getfiles (dirs [0]); var contentVal = get -getContent (файлы [0]); console.log ('filename:', contentval.file); console.log (contentval.content);});CO очень умный, и его основной код может упростить следующий пример. Общая идея состоит в том, чтобы использовать рекурсивный генератор обхода до тех пор, пока штат не будет завершен, конечно, CO делает больше.
RunGenerator (); function* run () {var dirs = hield getDirectories (); var files = Liking getFiles (dirs [0]); var contentVal = eilming getContent (файлы [0]); console.log ('filename:', contentval.file); console.log (contentVal.content);} функция runGenerator () {var gen = run (); функция go (result) {if (result.done) return; result.value.then (function (r) {go (gen.next (r));}); } go (gen.next ());}Es7 async/ждать
Генератор ES6 действительно хорош, но жаль, что мне нужна поддержка сторонней библиотеки. Хорошей новостью является то, что ES 7 представит ключевое слово Async/wave, чтобы идеально решить проблему асинхронных вызовов. Ну, .NET на один шаг впереди, и .NET Framework 4.5 уже первым, кто поддерживает его.
Будущий код будет написан так:
run (); Async function run () {var dirs = await getDirectories (); var files = await getFiles (dirs [0]); var contentVal = await getContent (файлы [0]); console.log ('filename:', contentval.file); console.log (contentval.content);}в заключение
От классического обратного асинхронного метода программирования, до улучшения асинхронного программирования с помощью спецификации обещания ES6, до элегантной обработки совместного объединения с генератором ES, и, наконец, идеального окончания ES7 Async/wative, мы можем понять, почему Ecmascript имеет эти функции и какие проблемы решают, и более четко видим разработку азинкорирования JavaScripccrip.