약속, 중국어는 단일 작업의 최종 결과를 나타내는 소원으로 이해될 수 있습니다. Promise에는 미완료(미완료), 이행(만족), 실패(실패)의 세 가지 상태가 있습니다. 이행 상태와 실패 상태를 모두 모니터링할 수 있습니다. 소원은 충족되지 않음 상태에서 충족 또는 실패 상태로 변경될 수 있습니다. 소원이 충족 또는 실패 상태가 되면 상태를 변경할 수 없습니다. 이 "불변" 기능은 Promise에 매우 중요합니다. Promise의 상태 리스너가 Promise의 상태를 수정하고 다른 리스너가 비정상적으로 동작하는 것을 방지할 수 있습니다. 예를 들어 이행 상태를 모니터링하는 리스너가 약속 상태를 실패로 변경하면 실패 상태의 리스너가 약속 상태를 이행으로 설정하면 리스너가 트리거됩니다. 이행된 상태에서는 장치가 트리거되어 무한 루프가 발생합니다. Promise의 특성을 이해하는 또 다른 방법은 Promise를 JavaScript의 기본 유형 변수로 생각하는 것입니다. 이 변수는 호출된 함수에 전달될 수 있지만 호출하는 함수에 의해 변경될 수는 없습니다.
각 Promise 객체에는 Promise의 다양한 상태를 모니터링하는 데 사용되는 then(fulfilledHandler, errorHandler, ProgressHandler) 메서드가 있습니다. fulledHandler는 이행된 이벤트를 수신하는 데 사용되고, errorHandler는 실패한 이벤트를 수신하는 데 사용되며, ProgressHandler는 진행 이벤트를 수신하는 데 사용됩니다. Promise는 진행 상태 이벤트 모니터링 구현을 강제하지 않습니다(jQuery의 Deferred는 Promise 구현이지만 진행 상태 이벤트 처리를 구현하지 않습니다).
then(...) 함수의fullchedHandler 및 errorHandler의 반환 값은 then(...) 함수를 체인으로 호출할 수 있도록 새로운 Promise 객체입니다. 각 콜백 함수는 정상적인 상황에서 이행된 상태의 Promise를 반환합니다. 콜백 함수가 오류 값을 반환하면 반환된 Promise 상태는 실패가 됩니다.
비동기 프로그래밍에서 Promise의 역할
비동기 모드는 웹 프로그래밍에서 점점 더 중요해지고 있습니다. 주류 웹 언어인 Javascript의 경우 이 모드는 구현하기가 그리 쉽지 않습니다. 이러한 이유로 많은 Javascript 라이브러리(예: jQuery 및 Dojo)에서는 소위 말하는 모드를 추가합니다. 이는 약속의 추상화입니다(때때로 지연이라고도 함). 이러한 라이브러리를 통해 개발자는 실제 프로그래밍에서 Promise 패턴을 사용할 수 있습니다.
Web 2.0 기술이 심화됨에 따라 브라우저 측에서는 점점 더 많은 컴퓨팅 압력을 받고 있으므로 "동시성"은 긍정적인 의미를 갖습니다. 개발자의 경우 페이지와 사용자 간의 상호 작용을 영향 없이 유지해야 할 뿐만 아니라 페이지와 비동기 작업 간의 관계를 조정해야 합니다. 이러한 종류의 비선형 실행 프로그래밍 요구 사항은 적응하기 어렵습니다. 페이지 상호 작용을 제쳐두고 비동기 호출을 위해 처리해야 하는 두 가지 결과, 즉 성공적인 작업과 실패 처리를 생각해 볼 수 있습니다. 호출이 성공한 후 다른 Ajax 요청에서 반환된 결과를 사용해야 할 수도 있으며, 이로 인해 "함수 체인" 상황이 발생합니다. 이러한 상황은 프로그래밍을 복잡하게 만듭니다. 다음 코드 예제를 살펴보십시오(XMLHttpRequest2 기반).
function searchTwitter(term, onload, onerror) { var xhr, results, url; url = 'http://search.twitter.com/search.json?rpp=100&q=' + term; xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.onload = function (e) { if (this.status === 200) { results = JSON.parse(this.responseText); onload(results); } }; xhr.onerror = function (e) { onerror(e); }; xhr.send(); } function handleError(error) { /* handle the error */ } function concatResults() { /* order tweets by date */ } function loadTweets() { var container = document.getElementById('container'); searchTwitter('#IE10', function (data1) { searchTwitter('#IE9', function (data2) { /* Reshuffle due to date */ var totalResults = concatResults(data1.results, data2.results); totalResults.forEach(function (tweet) { var el = document.createElement('li'); el.innerText = tweet.text; container.appendChild(el); }); }, handleError); }, handleError); }
위 코드의 기능은 트위터에서 IE10, IE9 해시태그가 포함된 콘텐츠를 가져와서 페이지에 표시하는 것입니다. 이러한 종류의 중첩된 콜백 함수는 이해하기 어렵습니다. 개발자는 어떤 코드가 애플리케이션의 비즈니스 로직에 사용되는지, 어떤 코드가 비동기 함수 호출을 처리하는지 주의 깊게 분석해야 합니다. 오류 처리도 분해되어 다양한 곳에서 오류 발생을 감지하고 그에 따라 처리해야 합니다.
비동기 프로그래밍의 복잡성을 줄이기 위해 개발자들은 비동기 작업을 처리하는 쉬운 방법을 찾고 있었습니다. 이러한 처리 패턴 중 하나를 약속(promise)이라고 하며, 이는 장기간 실행될 수 있고 반드시 완료될 필요는 없는 작업의 결과를 나타냅니다. 이 패턴은 긴 작업이 완료될 때까지 차단하고 기다리는 대신 약속된 결과를 나타내는 개체를 반환합니다.
페이지 코드가 타사 API에 액세스해야 하는 경우를 생각해 보세요. 네트워크 지연으로 인해 응답 시간이 길어질 수 있습니다. 이 경우 비동기 프로그래밍을 사용하면 전체 페이지와 사용자 간의 상호 작용에 영향을 미치지 않습니다. Promise 모드는 일반적으로 상태가 변경될 때 해당 콜백 함수를 등록하기 위해 then 호출되는 메서드를 구현합니다. 예를 들어 다음 코드 예는 다음과 같습니다.
searchTwitter(term).then(filterResults).then(displayResults);
promise模式在任何时刻都处于以下三种状态之一:未完成(unfulfilled)、已完成(resolved)和拒绝(rejected)。以CommonJS Promise/A 标准为例,promise对象上的then方法负责添加针对已完成和拒绝状态下的处理函数。then方法会返回另一个promise对象,以便于形成promise管道,这种返回promise对象的方式能够支持开发人员把异步操作串联起来,如then(resolvedHandler, rejectedHandler); 。resolvedHandler 回调函数在promise对象进入完成状态时会触发,并传递结果;rejectedHandler函数会在拒绝状态下调用。
有了promise模式,我们可以重新实现上面的Twitter示例。为了更好的理解实现方法,我们尝试着从零开始构建一个promise模式的框架。首先需要一些对象来存储promise。
var Promise = function () { /* initialize promise */ };
接下来,定义then方法,接受两个参数用于处理完成和拒绝状态。
Promise.prototype.then = function (onResolved, onRejected) { /* invoke handlers based upon state transition */ };
同时还需要两个方法来执行理从未完成到已完成和从未完成到拒绝的状态转变。
Promise.prototype.resolve = function (value) { /* move from unfulfilled to resolved */ }; Promise.prototype.reject = function (error) { /* move from unfulfilled to rejected */ };
现在搭建了一个promise的架子,我们可以继续上面的示例,假设只获取IE10的内容。创建一个方法来发送Ajax请求并将其封装在promise中。这个promise对象分别在xhr.onload和xhr.onerror中指定了完成和拒绝状态的转变过程,请注意searchTwitter函数返回的正是promise对象。然后,在loadTweets中,使用then方法设置完成和拒绝状态对应的回调函数。
function searchTwitter(term) { var url, xhr, results, promise; url = 'http://search.twitter.com/search.json?rpp=100&q=' + term; promise = new Promise(); xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.onload = function (e) { if (this.status === 200) { results = JSON.parse(this.responseText); promise.resolve(results); } }; xhr.onerror = function (e) { promise.reject(e); }; xhr.send(); return promise; } function loadTweets() { var container = document.getElementById('container'); searchTwitter('#IE10').then(function (data) { data.results.forEach(function (tweet) { var el = document.createElement('li'); el.innerText = tweet.text; container.appendChild(el); }); }, handleError); }
到目前为止,我们可以把promise模式应用于单个Ajax请求,似乎还体现不出promise的优势来。下面来看看多个Ajax请求的并发协作。此时,我们需要另一个方法when来存储准备调用的promise对象。一旦某个promise从未完成状态转化为完成或者拒绝状态,then方法里对应的处理函数就会被调用。when方法在需要等待所有操作都完成的时候至关重要。
Promise.when = function () { /* handle promises arguments and queue each */ };
以刚才获取IE10和IE9两块内容的场景为例,我们可以这样来写代码:
var container, promise1, promise2; container = document.getElementById('container'); promise1 = searchTwitter('#IE10'); promise2 = searchTwitter('#IE9'); Promise.when(promise1, promise2).then(function (data1, data2) { /* Reshuffle due to date */ var totalResults = concatResults(data1.results, data2.results); totalResults.forEach(function (tweet) { var el = document.createElement('li'); el.innerText = tweet.text; container.appendChild(el); }); }, handleError);
分析上面的代码可知,when函数会等待两个promise对象的状态发生变化再做具体的处理。在实际的Promise库中,when函数有很多变种,比如 when.some()、when.all()、when.any()等,读者从函数名字中大概能猜出几分意思来,详细的说明可以参考CommonJS的一个promise实现when.js。
除了CommonJS,其他主流的Javascript框架如jQuery、Dojo等都存在自己的promise实现。开发人员应该好好利用这种模式来降低异步编程的复杂性。我们选取Dojo为例,看一看它的实现有什么异同。
Dojo框架里实现promise模式的对象是Deferred,该对象也有then函数用于处理完成和拒绝状态并支持串联,同时还有resolve和reject,功能如之前所述。下面的代码完成了Twitter的场景:
function searchTwitter(term) { var url, xhr, results, def; url = 'http://search.twitter.com/search.json?rpp=100&q=' + term; def = new dojo.Deferred(); xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.onload = function (e) { if (this.status === 200) { results = JSON.parse(this.responseText); def.resolve(results); } }; xhr.onerror = function (e) { def.reject(e); }; xhr.send(); return def; } dojo.ready(function () { var container = dojo.byId('container'); searchTwitter('#IE10').then(function (data) { data.results.forEach(function (tweet) { dojo.create('li', { innerHTML: tweet.text }, container); }); }); });
不仅如此,类似dojo.xhrGet方法返回的即是dojo.Deferred对象,所以无须自己包装promise模式。
var deferred = dojo.xhrGet({ url: "search.json", handleAs: "json" }); deferred.then(function (data) { /* handle results */ }, function (error) { /* handle error */ });
除此之外,Dojo还引入了dojo.DeferredList,支持开发人员同时处理多个dojo.Deferred对象,这其实就是上面所提到的when方法的另一种表现形式。
dojo.require("dojo.DeferredList"); dojo.ready(function () { var container, def1, def2, defs; container = dojo.byId('container'); def1 = searchTwitter('#IE10'); def2 = searchTwitter('#IE9'); defs = new dojo.DeferredList([def1, def2]); defs.then(function (data) { // Handle exceptions if (!results[0][0] || !results[1][0]) { dojo.create("li", { innerHTML: 'an error occurred' }, container); return; } var totalResults = concatResults(data[0][1].results, data[1][1].results); totalResults.forEach(function (tweet) { dojo.create("li", { innerHTML: tweet.text }, container); }); }); });
上面的代码比较清楚,不再详述。
说到这里,读者可能已经对promise模式有了一个比较完整的了解,异步编程会变得越来越重要,在这种情况下,我们需要找到办法来降低复杂度,promise模式就是一个很好的例子,它的风格比较人性化,而且主流的JS框架提供了自己的实现。所以在编程实践中,开发人员应该尝试这种便捷的编程技巧。需要注意的是,promise模式的使用需要恰当地设置promise对象,在对应的事件中调用状态转换函数,并且在最后返回promise对象。

去掉重复并排序的方法:1、使用“Array.from(new Set(arr))”或者“[…new Set(arr)]”语句,去掉数组中的重复元素,返回去重后的新数组;2、利用sort()对去重数组进行排序,语法“去重数组.sort()”。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于Symbol类型、隐藏属性及全局注册表的相关问题,包括了Symbol类型的描述、Symbol不会隐式转字符串等问题,下面一起来看一下,希望对大家有帮助。

怎么制作文字轮播与图片轮播?大家第一想到的是不是利用js,其实利用纯CSS也能实现文字轮播与图片轮播,下面来看看实现方法,希望对大家有所帮助!

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于对象的构造函数和new操作符,构造函数是所有对象的成员方法中,最早被调用的那个,下面一起来看一下吧,希望对大家有帮助。

方法:1、利用“点击元素对象.unbind("click");”方法,该方法可以移除被选元素的事件处理程序;2、利用“点击元素对象.off("click");”方法,该方法可以移除通过on()方法添加的事件处理程序。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于面向对象的相关问题,包括了属性描述符、数据描述符、存取描述符等等内容,下面一起来看一下,希望对大家有帮助。

foreach不是es6的方法。foreach是es3中一个遍历数组的方法,可以调用数组的每个元素,并将元素传给回调函数进行处理,语法“array.forEach(function(当前元素,索引,数组){...})”;该方法不处理空数组。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于BOM操作的相关问题,包括了window对象的常见事件、JavaScript执行机制等等相关内容,下面一起来看一下,希望对大家有帮助。


핫 AI 도구

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

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

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

Clothoff.io
AI 옷 제거제

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

인기 기사

뜨거운 도구

mPDF
mPDF는 UTF-8로 인코딩된 HTML에서 PDF 파일을 생성할 수 있는 PHP 라이브러리입니다. 원저자인 Ian Back은 자신의 웹 사이트에서 "즉시" PDF 파일을 출력하고 다양한 언어를 처리하기 위해 mPDF를 작성했습니다. HTML2FPDF와 같은 원본 스크립트보다 유니코드 글꼴을 사용할 때 속도가 느리고 더 큰 파일을 생성하지만 CSS 스타일 등을 지원하고 많은 개선 사항이 있습니다. RTL(아랍어, 히브리어), CJK(중국어, 일본어, 한국어)를 포함한 거의 모든 언어를 지원합니다. 중첩된 블록 수준 요소(예: P, DIV)를 지원합니다.

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

Dreamweaver Mac版
시각적 웹 개발 도구

에디트플러스 중국어 크랙 버전
작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음

안전한 시험 브라우저
안전한 시험 브라우저는 온라인 시험을 안전하게 치르기 위한 보안 브라우저 환경입니다. 이 소프트웨어는 모든 컴퓨터를 안전한 워크스테이션으로 바꿔줍니다. 이는 모든 유틸리티에 대한 액세스를 제어하고 학생들이 승인되지 않은 리소스를 사용하는 것을 방지합니다.
