아마도 모든 JavaScript 개발자와 그 할머니는 Promise에 대해 들어보셨을 것입니다. 아직 하지 않으셨다면 곧 그렇게 될 것입니다. Promise의 개념은 Promises/A 사양에서 CommonJS 팀 구성원이 제안했습니다. Promise는 비동기 작업에 대한 콜백을 관리하는 방법으로 점점 더 많이 사용되고 있지만 설계상 그보다 훨씬 더 유용합니다. 사실, Promise의 다양한 용도로 인해 수많은 사람들이 제가 Promise에 대해 글을 쓴 후에 제가 Promise의 "요점을 놓치고 있다"고 말했습니다. 그러면 약속의 요점은 무엇입니까?
약속에 관한 것
Promise의 '핵심'에 대해 알아보기 전에 약속이 어떻게 작동하는지 좀 더 자세히 살펴보고 싶습니다. Promise/A 사양에 따르면 Promise는 단 하나의 메소드(then)만 요구하는 객체입니다. then 메소드는 성공 콜백, 실패 콜백, 전달 콜백(사양에서는 전달 콜백 구현을 포함하도록 요구하지 않지만 많은 경우 포함됨)의 세 가지 매개변수를 사용합니다. 각 then 호출에서 새로운 Promise 객체가 반환됩니다.
Promise는 미완료, 완료, 실패의 세 가지 상태 중 하나일 수 있습니다. 약속은 이행되지 않은 상태에서 시작됩니다. 성공하면 완료되고, 실패하면 실패합니다. Promise가 완료 상태로 전환되면 등록된 모든 성공 콜백이 호출되고 성공 결과 값이 전달됩니다. 또한 Promise에 등록된 성공 콜백은 완료 후 즉시 호출됩니다.
Promise가 실패 상태로 전환될 때에도 동일한 일이 발생합니다. 단, 성공 콜백 대신 실패 콜백을 호출합니다. 진행 기능을 포함하는 구현의 경우 약속은 이행되지 않은 상태를 떠나기 전에 언제든지 진행 상황을 업데이트할 수 있습니다. 진행률이 업데이트되면 모든 진행률 콜백에 진행률 값이 전달되고 즉시 호출됩니다. 진행 콜백은 성공 및 실패 콜백과 다르게 처리됩니다. 진행 업데이트가 발생한 후 진행 콜백을 등록하면 새 진행 콜백은 등록된 후에 업데이트된 진행에 대해서만 호출됩니다.
Promise 상태를 관리하는 방법은 사양 범위를 벗어나고 각 구현이 다르기 때문에 더 이상 설명하지 않겠습니다. 나중에 예제에서 어떻게 수행되는지 확인할 수 있지만 지금은 이것이 알아야 할 전부입니다.
콜백 처리
앞서 언급한 비동기 작업을 위한 콜백 처리는 Promise의 가장 기본적이고 일반적인 사용입니다. Promise를 사용하는 콜백과 표준 콜백을 비교해 보겠습니다.
// Normal callback usage asyncOperation(function() { // Here's your callback }); // Now `asyncOperation` returns a promise asyncOperation().then(function(){ // Here's your callback });
이 예시만 보고 실제로 Promise를 사용하고 싶은 사람이 있을지 모르겠습니다. "then"을 사용하면 비동기 작업이 완료된 후 콜백 함수가 호출된다는 점을 더 분명하게 알 수 있다는 점을 제외하면 이점이 없는 것 같습니다. 하지만 이러한 이점에도 불구하고 우리는 이제 더 많은 코드를 갖게 되었으며(추상화로 인해 코드가 더 짧아질 것입니다. 그렇죠?) Promise는 표준 콜백보다 성능이 약간 떨어집니다.
하지만 그렇다고 해서 멈추지 마세요. 이것이 promise가 할 수 있는 최선이었다면 이 글은 존재하지 않았을 것입니다
파멸의 피라미드
// Normal callback usage => PYRAMID OF DOOOOOOOOM asyncOperation(function(data){ // Do some processing with `data` anotherAsync(function(data2){ // Some more processing with `data2` yetAnotherAsync(function(){ // Yay we're finished! }); }); }); // Let's look at using promises asyncOperation() .then(function(data){ // Do some processing with `data` return anotherAsync(); }) .then(function(data2){ // Some more processing with `data2` return yetAnotherAsync(); }) .then(function(){ // Yay we're finished! });
正如你所见,promises的使用使得事情变扁平而且更可读了。这能起作用是因为——像早先提到的——then返回了一个promise,所以你可以将then的调用不停的串连起来。由then返回的promise装载了由调用返回的值。如果调用返回了一个promise(像这个例子中的情形一样),then返回的 promise装载了与你的回调返回的promise所装载的相同值。这内容很多,因此我将帮助你一步一步的理解它
异步操作返回一个promise对象。因此我们在那个promise对象中调用then,并且传给它一个回调函数;then也会返回一个promise。当异步操作结束,它将给promise装上数据。然后(第一次)回调被调用,数据被作为参数传递进去。如果回调不含有返回值,then返回的promise将会立即不带值组装。如果回调返回的不是一个promise,那么then返回的 promise将会立即装载那个数值。如果回调返回一个promise(像例子中的),那么then返回的 promise将等待直到我们回调返回的promise被完全装载。一旦我们回调的 promise被装载,它装载的值(本例中就是data2)将会被提交给then的promise。然后then中的promise装载了data2。等等。听起来有点复杂,但事实上很简单,如果我说的你不能理解,我非常抱歉。我猜我可能不是谈论它的最佳人选。
用命名的回调替代
但显然 promises 不是使这个结构扁平化的唯一方法。在写了一篇提到promises解决了厄运的金字塔问题的帖子之后,有个人对该帖评论说……
我想promises有时是有用的,但是“嵌套”的回调的问题(圣诞树综合症)可以仅用一个命名的函数作为一个参数替代匿名函数的方法平常的处理:
asyncCall( param1, param2, HandlerCallback ); function HandlerCallback(err, res){ // do stuff }
它的例子只是给出了一层深的例子,但它仍是正确的。我们来扩展我前面的例子,使这个看起来容易些。
命名回调
// Normal callback usage => PYRAMID OF DOOOOOOOOM asyncOperation(handler1); function handler1(data) { // Do some processing with `data` anotherAsync(handler2); } function handler2(data2) { // Some more processing with `data2` yetAnotherAsync(handler3); } function handler3() { // Yay we're finished! }
看看上面的代码!他们绝对是对的!它就是一个扁平的结构,但是这里有个问题同样也存在于 我以前从来没有注意过的老的回调例子中:依赖性和复用性。依赖性和复用性是相互关联的可逆类型。一样东西依赖的越少,那么它的复用性就越大。在以上的例子中,handler1依赖handler2,handler2依赖handler3.这就意味着handler1无论出于任何目的都不可在被用除非handler2也呈现出来。假如你不打算重用他们,那么给你的函数命名又有什么意义呢?
最糟糕的的是handler1都不关心在handler2里面发生了什么事情。它压根就不需要handler2除了和它异步工作。因此,让我们消除这些依赖性然后通过用promise使函数更具复用性。
链式回调
asyncOperation().then(handler1).then(handler2).then(handler3); function handler1(data) { // Do some processing with `data` return anotherAsync(); } function handler2(data2) { // Some more processing with `data2` return yetAnotherAsync(); } function handler3() { // Yay we're finished! }
这样看起来是不是好多了?假如另外的函数存在的话,现在handler1和handler2都互不相关了。想看看他们是否真的很棒呢?现在handler1可以被用在不需要handler2的情况下了。相反,handler1被操作以后,我们将可以用另一个handler。
复用函数
asyncOperation().then(handler1).then(anotherHandler); function handler1(data) { // Do some processing with `data` return anotherAsync(); } function anotherHandler(data2) { // Do some really awesome stuff that you've never seen before. It'll impress you }
现在handler1已经从handler2脱离而且可以被用在了更多的情形中,特别是那些由handler2提供的功能而我们又不想用的。这就是复用性!评论家解决代码易读性的唯一方法就是通过消除缩进。我们不想消除缩进仅仅是为了缩进。多层次的缩进仅仅是某些事情错误的标志,问题不一定在它本身。他就像是由脱水引起的头痛。真正的问题是脱水,不是头痛。解决的方法是获得水合物,而不是用一些止痛药。
并行异步操作
在前面我提到的文章里,我将promises与events在处理异步操作方面做了比较。遗憾的是,按照那些曾提到过的人在评论里给的说法,我比较的不是很成功。我描述出了promises的力量,接着转到events来描述它们的力量,就像在我的特别项目里用到的那样。没有比较和对比。一位评论者写道(修改了一点语法错误):
我想用帖子中的例子是一个坏的对照。有篇论文证明了promises的值将会怎样,如果按下虚构的“启动服务器按钮”,将不仅仅是启动一个web服务器,还有一个数据库服务器,当它们都在运行的时候只是更新了UI。
使用promise的.when方法将会使这种“多个异步操作”例子变得普通,然而响应多个异步事件需要一个并不普通的代码量。
他完全正确。事实上我没有比较那两种情况。那篇文章的要点实际在于说明promises不是异步操作的唯一机制,而且在一些情况下,它们也不一定是最好的。在这个评论者指出的情况下,promises当然是最佳的解决办法。我们来看看他说的是什么
jQuery 具有 一个名为when的方法 ,可以带上任意数量的promise参数,并返回一个单一的promise。如果任何一个promise传入失败,when返回的promise也会失败。如果所有的promises被装载,那么每个值都将会按照promises被定义的顺序传递给附加的回调。
以并行的方式执行无数的异步操作非常有用,然后只要在它们之中的每一个结束之后继续执行回调。我们看一个简单的例子。
jQuery.when
// Each of these async functions return a promise var promise1 = asyncOperation1(); var promise2 = asyncOperation2(); var promise3 = asyncOperation3(); // The $ refers to jQuery $.when(promise1, promise2, promise3).then( function(value1, value2, value3){ // Do something with each of the returned values } );
사람들은 종종 이것이 약속의 가장 좋은 점 중 하나이며 약속을 중요하게 만드는 이유 중 하나라고 말합니다. 나는 또한 이것이 많은 작업을 단순화하는 좋은 기능이라고 생각하지만, Promises 사양에 메서드가 전혀 언급되지 않은 경우 이 메커니즘이 Promises의 핵심은 아니라고 생각합니다. when 메소드를 언급하는 스펙이 있는데, 위와는 전혀 다릅니다. 내가 아는 한, jQuery는 이 when 메서드를 구현하는 유일한 라이브러리입니다. Q, Dojo 및 when과 같은 다른 promise 라이브러리는 Promises/B 사양에 따라 when 메서드를 구현하지만 해설자가 언급한 when 메서드는 구현하지 않습니다. 그러나 Q 라이브러리에는 all 메서드가 있고 when.js에도 병렬 메서드가 있습니다. 이 메서드는 임의 개수의 매개변수 대신 배열 유형 매개변수를 허용한다는 점을 제외하면 위의 jQuery.when 메서드와 동일하게 작동합니다.
가치의 표현
Promise는 다음 시나리오를 처리하는 더 좋은 방법입니다.
"이 데이터베이스에서 사용자를 찾고 싶지만 찾기 방법이 비동기식입니다."
여기에는 값을 즉시 반환할 수 없는 find 메소드가 있습니다. 그러나 궁극적으로 콜백을 통해 값을 "반환"하고 사용자는 어떤 방식으로든 해당 값을 처리하려고 합니다. 이제 콜백을 사용하여 연속 또는 "나중에 해당 값을 처리할 일부 코드"를 정의할 수 있습니다.
Promise는 "여기 반환 값을 처리하는 데 사용할 코드가 있습니다"로 변경합니다. 이는 "find" 메서드가 "야, 나는 당신이 찾고 있는 정보를 찾느라 바쁠 것 같지만 그 동안에는 결과가 반환될 때까지 계속 기다릴 수 있으며, Real stuff처럼 원하는 방식으로 동시에 처리할 수 있어요!”
약속은 진정한 가치를 나타냅니다. 그게 함정이에요. Promise를 실제처럼 처리할 때 작동합니다. Promise의 JavaScript 구현에서는 콜백 함수를 전달할 것으로 예상합니다. 이는 단지 "우연"일 뿐 중요한 것은 아닙니다.
저는 이것이 바로 약속의 핵심이라고 믿습니다. 왜? Promise/A 사양의 첫 번째 문장인 "Promise는 작업 완료로 반환되는 값을 나타냅니다."를 읽어보면 좀 더 명확해지지 않습니까? 글쎄요, 그것이 요점이라 할지라도 이 기사의 뒷부분에서 다른 사람들의 통찰력을 제시하는 것을 막지는 않습니다. 어쨌든, 이 아이디어에 대해 좀 더 이야기해 보겠습니다.
결론
Promise의 핵심은 작업에서 반환된 최종 결과 값을 나타내는 것이지만 이를 사용하는 이유는 동기 작업의 병렬성을 향상시키기 위한 것입니다. 비동기 프로그래밍이 등장한 이후로 콜백이 모든 곳에서 나타나 이상한 방식으로 코드를 모호하게 만들었습니다. 약속은 그것을 바꾸는 방법입니다. Promise를 사용하면 코드를 비동기식으로 실행하면서 동기식으로 코드를 작성할 수 있습니다.

Python은 부드러운 학습 곡선과 간결한 구문으로 초보자에게 더 적합합니다. JavaScript는 가파른 학습 곡선과 유연한 구문으로 프론트 엔드 개발에 적합합니다. 1. Python Syntax는 직관적이며 데이터 과학 및 백엔드 개발에 적합합니다. 2. JavaScript는 유연하며 프론트 엔드 및 서버 측 프로그래밍에서 널리 사용됩니다.

Python과 JavaScript는 커뮤니티, 라이브러리 및 리소스 측면에서 고유 한 장점과 단점이 있습니다. 1) Python 커뮤니티는 친절하고 초보자에게 적합하지만 프론트 엔드 개발 리소스는 JavaScript만큼 풍부하지 않습니다. 2) Python은 데이터 과학 및 기계 학습 라이브러리에서 강력하며 JavaScript는 프론트 엔드 개발 라이브러리 및 프레임 워크에서 더 좋습니다. 3) 둘 다 풍부한 학습 리소스를 가지고 있지만 Python은 공식 문서로 시작하는 데 적합하지만 JavaScript는 MDNWebDocs에서 더 좋습니다. 선택은 프로젝트 요구와 개인적인 이익을 기반으로해야합니다.

C/C에서 JavaScript로 전환하려면 동적 타이핑, 쓰레기 수집 및 비동기 프로그래밍으로 적응해야합니다. 1) C/C는 수동 메모리 관리가 필요한 정적으로 입력 한 언어이며 JavaScript는 동적으로 입력하고 쓰레기 수집이 자동으로 처리됩니다. 2) C/C를 기계 코드로 컴파일 해야하는 반면 JavaScript는 해석 된 언어입니다. 3) JavaScript는 폐쇄, 프로토 타입 체인 및 약속과 같은 개념을 소개하여 유연성과 비동기 프로그래밍 기능을 향상시킵니다.

각각의 엔진의 구현 원리 및 최적화 전략이 다르기 때문에 JavaScript 엔진은 JavaScript 코드를 구문 분석하고 실행할 때 다른 영향을 미칩니다. 1. 어휘 분석 : 소스 코드를 어휘 단위로 변환합니다. 2. 문법 분석 : 추상 구문 트리를 생성합니다. 3. 최적화 및 컴파일 : JIT 컴파일러를 통해 기계 코드를 생성합니다. 4. 실행 : 기계 코드를 실행하십시오. V8 엔진은 즉각적인 컴파일 및 숨겨진 클래스를 통해 최적화하여 Spidermonkey는 유형 추론 시스템을 사용하여 동일한 코드에서 성능이 다른 성능을 제공합니다.

실제 세계에서 JavaScript의 응용 프로그램에는 서버 측 프로그래밍, 모바일 애플리케이션 개발 및 사물 인터넷 제어가 포함됩니다. 1. 서버 측 프로그래밍은 Node.js를 통해 실현되며 동시 요청 처리에 적합합니다. 2. 모바일 애플리케이션 개발은 재교육을 통해 수행되며 크로스 플랫폼 배포를 지원합니다. 3. Johnny-Five 라이브러리를 통한 IoT 장치 제어에 사용되며 하드웨어 상호 작용에 적합합니다.

일상적인 기술 도구를 사용하여 기능적 다중 테넌트 SaaS 응용 프로그램 (Edtech 앱)을 구축했으며 동일한 작업을 수행 할 수 있습니다. 먼저, 다중 테넌트 SaaS 응용 프로그램은 무엇입니까? 멀티 테넌트 SAAS 응용 프로그램은 노래에서 여러 고객에게 서비스를 제공 할 수 있습니다.

이 기사에서는 Contrim에 의해 확보 된 백엔드와의 프론트 엔드 통합을 보여 주며 Next.js를 사용하여 기능적인 Edtech SaaS 응용 프로그램을 구축합니다. Frontend는 UI 가시성을 제어하기 위해 사용자 권한을 가져오고 API가 역할 기반을 준수하도록합니다.

JavaScript는 현대 웹 개발의 핵심 언어이며 다양성과 유연성에 널리 사용됩니다. 1) 프론트 엔드 개발 : DOM 운영 및 최신 프레임 워크 (예 : React, Vue.js, Angular)를 통해 동적 웹 페이지 및 단일 페이지 응용 프로그램을 구축합니다. 2) 서버 측 개발 : Node.js는 비 차단 I/O 모델을 사용하여 높은 동시성 및 실시간 응용 프로그램을 처리합니다. 3) 모바일 및 데스크탑 애플리케이션 개발 : 크로스 플랫폼 개발은 개발 효율을 향상시키기 위해 반응 및 전자를 통해 실현됩니다.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

ZendStudio 13.5.1 맥
강력한 PHP 통합 개발 환경

PhpStorm 맥 버전
최신(2018.2.1) 전문 PHP 통합 개발 도구

SecList
SecLists는 최고의 보안 테스터의 동반자입니다. 보안 평가 시 자주 사용되는 다양한 유형의 목록을 한 곳에 모아 놓은 것입니다. SecLists는 보안 테스터에게 필요할 수 있는 모든 목록을 편리하게 제공하여 보안 테스트를 더욱 효율적이고 생산적으로 만드는 데 도움이 됩니다. 목록 유형에는 사용자 이름, 비밀번호, URL, 퍼징 페이로드, 민감한 데이터 패턴, 웹 셸 등이 포함됩니다. 테스터는 이 저장소를 새로운 테스트 시스템으로 간단히 가져올 수 있으며 필요한 모든 유형의 목록에 액세스할 수 있습니다.

DVWA
DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는

VSCode Windows 64비트 다운로드
Microsoft에서 출시한 강력한 무료 IDE 편집기
