>  기사  >  웹 프론트엔드  >  es6 콜백 지옥이란 무엇입니까?

es6 콜백 지옥이란 무엇입니까?

青灯夜游
青灯夜游원래의
2023-02-14 14:58:541929검색

es6에서 콜백 지옥은 서로 중첩된 다중 계층 콜백 함수입니다. 즉, 콜백 함수에 중첩된 콜백 함수는 코드의 순차적 실행을 달성하기 위해 발생하는 작업이며 코드를 읽을 수 있게 만듭니다. 매우 열악하고 나중에 유지 관리하기가 어렵습니다. es6에서는 콜백 지옥 문제를 해결하기 위해 Promise를 사용합니다.

es6 콜백 지옥이란 무엇입니까?

이 튜토리얼의 운영 환경: Windows 7 시스템, ECMAScript 버전 6, Dell G3 컴퓨터.

머리말

"콜백 지옥"을 공식적으로 이해하기 전에 먼저 두 가지 개념을 이해해야 합니다.

1. 콜백 함수

함수가 다른 매개변수에 매개변수로 전달되지만 그렇지 않은 경우 즉시 실행됩니다. 이 함수는 특정 조건이 충족되는 경우에만 실행될 수 있습니다. 이 함수를 콜백 함수라고 합니다. 타이머와 Ajax에는 우리에게 익숙한 콜백 함수가 있습니다:

setTimeout(function(){   //function(){console.log('执行了回调函数')}就是回调函数,它只有在3秒后才会执行
	console.log('执行了回调函数');
},3000)  //3000毫秒

여기서 콜백 함수는 function(){console.log('Callback function running')}입니다. 시간 3이 met 초 후에 실행됩니다. function(){console.log('执行了回调函数')},在满足时间3秒后执行。

//1.创建异步对象
			var xhr=new XMLHttpRequest();
      //2.绑定监听事件(接收请求)
			xhr.onreadystatechange=function(){
				//此方法会被调用4次
				//最后一次,readyState==4
				//并且响应状态码为200时,才是我们要的响应结果 xhr.status==200
				if(xhr.readyState==4 && xhr.status==200){
					//把响应数据存储到变量result中
					var result=xhr.responseText;
					console.log(result);
				}
			}
      //3.打开链接(创建请求)
			xhr.open("get","/demo/ajaxDemo",true);
      //4.发送请求
			xhr.send();

这里的回调函数是xhr.onreadystatechange绑定的函数,在xhr.send()发送请求并拿到响应后执行。

2、异步任务

与之相对应的概念是“同步任务”,同步任务在主线程上排队执行,只有前一个任务执行完毕,才能执行下一个任务。异步任务不进入主线程,而是进入异步队列,前一个任务是否执行完毕不影响下一个任务的执行。同样,还拿定时器作为异步任务举例:

setTimeout(function(){
    console.log('执行了回调函数');
},3000)
console.log('111');

如果按照代码编写的顺序,应该先输出“执行了回调函数”,再输出“111”。但实际输出为:
es6 콜백 지옥이란 무엇입니까?
这种不阻塞后面任务执行的任务就叫做异步任务。

接下来让我们看看什么是回调地狱。

一、回调地狱是什么?

根据前面我们可以得出一个结论:存在异步任务的代码,不能保证能按照顺序执行,那如果我们非要代码顺序执行呢?

比如我要说一句话,语序必须是下面这样的:武林要以和为贵,要讲武德,不要搞窝里斗。
我必须要这样操作,才能保证顺序正确:

        setTimeout(function () {  //第一层
            console.log('武林要以和为贵');
            setTimeout(function () {  //第二程
                console.log('要讲武德');
                setTimeout(function () {   //第三层
                    console.log('不要搞窝里斗');
                }, 1000)
            }, 2000)
        }, 3000)

es6 콜백 지옥이란 무엇입니까?

可以看到,代码中的回调函数套回调函数,居然套了3层,这种回调函数中嵌套回调函数的情况就叫做回调地狱。

总结一下,回调地狱就是为是实现代码顺序执行而出现的一种操作,它会造成我们的代码可读性非常差,后期不好维护。

那该如何解决回调地狱呢?

二、如何解决回调地狱

1.Promise

Promise是js中的一个原生对象,是一种异步编程的解决方案,可以替换掉传统的回调函数解决方案。

  • Promise构造函数接收一个函数作为参数,我们需要处理的异步任务就卸载该函数体内,该函数的两个参数是resolve,reject。异步任务执行成功时调用resolve函数返回结果,反之调用reject。

  • Promise对象的then方法用来接收处理成功时响应的数据,catch方法用来接收处理失败时相应的数据。

  • Promise的链式编程可以保证代码的执行顺序,前提是每一次在than做完处理后,一定要return一个Promise对象,这样才能在下一次then时接收到数据。

下面是实例代码:

        function fn(str){
            var p=new Promise(function(resolve,reject){
                //处理异步任务
                var flag=true;
                setTimeout(function(){
                    if(flag){
                        resolve(str)
                    }
                    else{
                        reject('操作失败')
                    }
                })
            })
            return p;
        }

        fn('武林要以和为贵')
        .then((data)=>{
            console.log(data);
            return fn('要讲武德');
        })
        .then((data)=>{
            console.log(data);
            return fn('不要搞窝里斗')
        })
        .then((data)=>{
            console.log(data);
        })
        .catch((data)=>{
            console.log(data);
        })

es6 콜백 지옥이란 무엇입니까?
但是Promise最大的问题就是代码冗余,原来的异步任务被Promise封装一下,不管什么操作都用than,就会导致一眼看过去全是then…then…then…,这样也是不利于代码维护的。

所以下面的async/await 可以时代码看起来更像同步代码。

2.async/await

首先我们看async

        async function fn(){
            return '不讲武德';
        }
        console.log(fn());
여기서 콜백 함수는 xhr.onreadystatechange에 바인딩된 함수로, xhr.send()가 요청을 보내고 응답을 받은 후에 실행됩니다.

es6 콜백 지옥이란 무엇입니까?
2. 비동기 작업

동기 작업은 이전 작업이 완료되어야만 다음 작업이 실행될 수 있습니다. 비동기 작업은 메인 스레드에 들어가지 않고 비동기 큐에 들어갑니다. 이전 작업이 완료되었는지 여부는 다음 작업 실행에 영향을 주지 않습니다. 마찬가지로 타이머를 비동기 작업의 예로 들어보겠습니다. 🎜
        async function fn() {
            var flag = true;
            if (flag) {
                return '不讲武德';
            }
            else{
                throw '处理失败'
            }
        }
        fn()
        .then(data=>{
            console.log(data);
        })
        .catch(data=>{
            console.log(data);
        })

        console.log('先执行我,表明async声明的函数是异步的');
🎜코드 작성 순서를 따르면 "콜백 함수 실행됨"이 먼저 출력되고 그 다음에는 "111"이 출력되어야 합니다. 그러나 실제 출력은 다음과 같습니다. 🎜🎜 후속 작업의 실행을 차단하지 않는 작업을 비동기 작업이라고 합니다. 🎜🎜다음으로 콜백 지옥이 무엇인지 살펴보겠습니다. 🎜🎜🎜🎜1. 콜백지옥이란? 🎜🎜🎜위를 바탕으로 결론을 내릴 수 있습니다. 비동기 작업을 위한 코드가 있지만 순서대로 실행된다는 보장은 없습니다. 🎜🎜예를 들어 문장을 말하고 싶다면 어순은 다음과 같아야 합니다. 무술계에서는 평화를 소중히 여겨야 하고, 무예를 존중해야 하며, 싸움을 피해서는 안 됩니다. 🎜 올바른 순서를 보장하려면 다음을 수행해야 합니다. 🎜
        //封装一个返回promise的异步任务
        function fn(str) {
            var p = new Promise(function (resolve, reject) {
                var flag = true;
                setTimeout(function () {
                    if (flag) {
                        resolve(str)
                    } else {
                        reject('处理失败')
                    }
                })
            })
            return p;
        }

        //封装一个执行上述异步任务的async函数
        async function test(){
            var res1=await fn('武林要以和为贵');  //await直接拿到fn()返回的promise的数据,并且赋值给res
            var res2=await fn('要讲武德');
            var res3=await fn('不要搞窝里斗');
            console.log(res1,res2,res3);
        }
        //执行函数
        test();
🎜at 여기에 그림 설명 삽입 🎜🎜보시다시피 코드의 콜백 함수는 3개 계층의 콜백 함수 내에 중첩되어 있습니다. 이러한 콜백 함수 내에 콜백 함수가 중첩되는 상황을 콜백 지옥이라고 합니다. 🎜🎜요약하자면, 콜백 지옥은 코드의 순차적 실행을 달성하기 위해 발생하는 작업입니다. 이로 인해 코드가 매우 읽기 어렵고 나중에 유지 관리가 어려워집니다. 🎜🎜그럼 콜백 지옥을 해결하는 방법은 무엇일까요? 🎜🎜
🎜🎜2. 콜백 지옥을 해결하는 방법🎜🎜🎜🎜1. Promise🎜🎜 Promise는 js의 기본 객체이며 일종의 비동기 프로그래밍입니다. 솔루션은 기존 콜백 함수 솔루션을 대체할 수 있습니다. 🎜
  • 🎜Promise 생성자는 함수를 매개변수로 받습니다. 처리해야 하는 비동기 작업은 이 함수의 두 매개변수로 언로드됩니다. 결심하다, 거절하다. 비동기 작업이 성공적으로 실행되면 결과를 반환하기 위해 해결 함수가 호출되고, 그렇지 않으면 거부가 호출됩니다. 🎜
  • 🎜Promise 객체의 then 메소드는 처리 성공 시 응답 데이터를 받기 위해 사용되고, catch 메소드는 처리 실패 시 해당 데이터를 받기 위해 사용됩니다. 🎜
  • 🎜Promise의 체인 프로그래밍은 코드의 실행 순서를 보장할 수 있습니다. 전제는 than을 처리한 후 매번 Promise 객체를 반환해야 데이터를 받을 수 있다는 것입니다. 다음엔 그럼. 🎜
🎜다음은 예제 코드입니다: 🎜rrreee🎜여기에 그림 설명 삽입🎜 하지만 Promise의 가장 큰 문제점은 코드 중복입니다. 원래 비동기 작업은 Promise에 의해 캡슐화됩니다. 어떤 작업에 than을 사용하면 then...then.. .그렇다면 언뜻 보기에 ... 이는 코드 유지 관리에도 도움이 되지 않습니다. 🎜🎜따라서 다음 async/await가 작동하고 코드는 동기 코드와 더 비슷해 보입니다. 🎜🎜
🎜🎜2.async/await🎜🎜🎜먼저 async를 살펴보겠습니다. 키워드는 선언된 함수 앞에 키워드로 배치되어 함수가 비동기 작업이며 후속 함수의 실행을 차단하지 않음을 나타냅니다. 🎜rrreee🎜🎜🎜 비동기 함수가 데이터를 반환할 때 이를 볼 수 있습니다. Promise 객체에 자동으로 캡슐화됩니다. 🎜🎜Promise 객체와 마찬가지로 비동기 작업을 처리할 때 성공과 실패에 따라 다른 데이터를 반환할 수도 있습니다. 처리가 성공하면 then 메서드를 사용하여 수신하고, 실패하면 catch 메서드를 사용하여 데이터를 받습니다. : 🎜
        async function fn() {
            var flag = true;
            if (flag) {
                return '不讲武德';
            }
            else{
                throw '处理失败'
            }
        }
        fn()
        .then(data=>{
            console.log(data);
        })
        .catch(data=>{
            console.log(data);
        })

        console.log('先执行我,表明async声明的函数是异步的');

es6 콜백 지옥이란 무엇입니까?
当把flag设置为false是,执行结果为:
es6 콜백 지옥이란 무엇입니까?
async关键字说完了,我们看看awai关键字

  • await关键字只能在使用async定义的函数中使用
  • await后面可以直接跟一个 Promise实例对象(可以跟任何表达式,更多的是跟一个返回Promise对象的表达式)
  • await函数不能单独使用
  • await可以直接拿到Promise中resolve中的数据。
        //封装一个返回promise的异步任务
        function fn(str) {
            var p = new Promise(function (resolve, reject) {
                var flag = true;
                setTimeout(function () {
                    if (flag) {
                        resolve(str)
                    } else {
                        reject('处理失败')
                    }
                })
            })
            return p;
        }

        //封装一个执行上述异步任务的async函数
        async function test(){
            var res1=await fn('武林要以和为贵');  //await直接拿到fn()返回的promise的数据,并且赋值给res
            var res2=await fn('要讲武德');
            var res3=await fn('不要搞窝里斗');
            console.log(res1,res2,res3);
        }
        //执行函数
        test();

结果为:
es6 콜백 지옥이란 무엇입니까?
为什么叫await等待呢,因为当代码执行到async函数中的await时,代码就在此处等待不继续往下执行,知道await拿到Promise对象中resolve的数据,才继续往下执行,这样就保证了代码的执行顺序,而且使异步代码看起来更像同步代码。

总结

总结一下,当我们写代码遇到异步回调时,我们想让异步代码按照我们想要的顺序执行,如果按照传统的嵌套方式,就会出现回调地狱,这样的代码不利于维护,我们可以通过Promise对象进行链式编程来解决,这样尽管可以解决问题,但是ES7给我们提供了更加舒适的async/await语法糖,可以使得异步代码看起来更像是同步代码。

【相关推荐:javascript视频教程web前端

위 내용은 es6 콜백 지옥이란 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.