>웹 프론트엔드 >JS 튜토리얼 >ECMAScript6의 Promise란 무엇입니까? 무슨 소용이 있나요? (예제 포함)

ECMAScript6의 Promise란 무엇입니까? 무슨 소용이 있나요? (예제 포함)

不言
不言앞으로
2018-10-24 11:44:472083검색

이 글의 내용은 ECMAScript6의 Promise란 무엇인가요? 무슨 소용이 있나요? (예시 포함) 참고할만한 가치가 있으니 도움이 필요한 친구들이 참고하시면 좋을 것 같습니다.

방금 공부를 끝냈는데 느낌이 좀 심하네요. 후속 연구를 위해 정리하고 기록하고 이해를 심화하기 위해 보충합니다.

Promise란 무엇입니까

Promise는 new를 통해 Promise 객체를 생성할 수 있는 생성자입니다.

Promise의 용도는 무엇인가요

현재 느낌은 비동기식 프로세스를 운영하는 것이 더 편리하고, 이벤트 제어 프로세스가 더 명확하고 직관적이며, 체인으로 호출할 수 있다는 것입니다

Promise 기능

ES6 Getting Started에서 발췌

Promise Object는 다음과 같은 두 가지 특징을 가지고 있습니다.
(1) 물체의 상태는 외부 세계의 영향을 받지 않습니다. Promise 객체는 비동기 작업을 나타내며 보류(진행 중), 이행(성공), 거부(실패)의 세 가지 상태를 갖습니다. 비동기 작업의 결과만 현재 상태를 확인할 수 있으며 다른 작업은 이 상태를 변경할 수 없습니다. 이것이 Promise라는 이름의 유래이기도 합니다. 영어 의미는 "commitment"이며, 이는 다른 방법으로 변경할 수 없다는 의미입니다.
(2) 상태는 한 번 변경되면 다시 변경되지 않으며, 이 결과는 언제든지 얻을 수 있습니다. Promise 객체의 상태가 변경되는 경우는 보류에서 이행으로, 보류에서 거부로 두 가지뿐입니다. 이 두 가지 상황이 발생하는 한 상태는 굳어져 다시는 변하지 않고 이 결과를 유지한다고 합니다. 해결되었습니다. 이미 변경이 발생한 경우 Promise 객체에 콜백 함수를 추가하면 즉시 결과를 얻을 수 있습니다. 이는 이벤트와는 전혀 다른 이벤트의 특징은 놓치고 다시 들으면 결과가 나오지 않는다는 점입니다.

몇 가지 간단한 예를 통해 이해하세요

new를 통해 간단한 Promise 객체를 구성하세요

let p = new Promise((resolve, reject) => {});

전달된 두 매개변수는 Promise 객체의 상태를 제어하는 ​​데 사용됩니다. p를 인쇄하여 상태를 확인하겠습니다.
Promise {__proto__: Promise[[PromiseStatus]]: "pending"[[PromiseValue]]: 정의되지 않음이것은 보류 중인 초기 상태입니다Promise {__proto__: Promise[[PromiseStatus]]: "pending"[[PromiseValue]]: undefined这个就是初始状态pending
而resolve,reject可以控制Promise的状态

//resolve()
let p = new Promise((resolve, reject) => resolve("123")); //Promise {<resolved>: "123"}
//reject()
let p = new Promise((resolve, reject) => reject("123")); //reject()后是返回一个失败状态的Promise,不需要用catch来捕获不写catch会报错
p.catch(data => console.log(data));    
console.log(p);    //Promise {<rejected>: "123"}   123

提到了catch那就有还有一个then
 说一直白点:then(f1, f2)可以填入两个函数参数,一个参数就是将resolve中参数代入f1来执行,第二个参数将reject中参数代入f2来执行;第二个参数可以用catch来代替,并且它更加强大,catch能捕获then()中的报错

let p = new Promise((resolve, reject) => {
    
    let n = Math.ceil(Math.random() * 10);
    n > 5 ? resolve(n) : reject(n);
});
p.then(
    data => console.log(data),
    data => console.log(data),
)

用catch代替,并捕获then的错误

let p = new Promise((resolve, reject) => {
    
    resolve("yes")
});
p.then(
    data => {console.log(data),console.log(a)}

).catch(data => console.log(data));
//yes
//ReferenceError: a is not defined

因为then处理后返回的还是Promise对象,这样方便链式调用,then中都没有return,怎么会有Promise对象的呢?

then或catch即使未显式指定返回值, 它们也总是自动包装一个新的fulfilled状态的promise对象。

我们打印一下会发现:Promise {<resolved>: undefined}
  那么我们可以显示的return一个Promise对象看看,

let p = new Promise((resolve, reject) => resolve("yes"));
p.then(data => Promise.resolve("第二个Promise")).then(data => console.log(data));   //第二个Promise

可以看到p.then(data => Promise.resolve("第二个Promise"))返回Promise对象是Promise {<resolved>: "第二个Promise"}그리고 해결 및 거부는 Promise의 상태를 제어할 수 있습니다

Promise.resolve('f')
// 等价于
new Promise(resolve => resolve('f'))
let thenable = {
    then :(resolve, reject) => resolve("thenable")
}

let p = Promise.resolve(thenable);
console.log(p);

catch를 언급했다면, 또 다른 then이 있습니다
직설적으로 말하면 then(f1, f2)는 두 개의 함수 매개변수를 채울 수 있습니다. 한 매개변수는 실행을 위해 분석의 매개변수를 f1로 대체하는 것이고, 두 번째 매개변수는 거부의 매개변수를 대체하는 것입니다. 두 매개변수는 catch로 대체될 수 있으며, catch는 then()

let p1 = new Promise((resolve, reject) => false);
let p = Promise.resolve(p1);
console.log(p);

에서 오류를 캡처할 수 있으며 대신 catch를 사용하고 Promise 개체가 다음과 같기 때문에

const thenable = {
  then(resolve, reject) {
    reject('出错了');
  }
};

Promise.reject(thenable)
.catch(e => {
  console.log(e === thenable)
})
의 오류를 캡처할 수 있습니다. 처리 후 반환되므로 편리합니다. 체인 호출에서는 반환이 없는데 어떻게 Promise 개체가 있을 수 있습니까?

then or catch는 반환 값이 명시적으로 지정되지 않은 경우에도 항상 새로운 이행 상태 약속 객체를 자동으로 래핑합니다.

인쇄하면 다음을 찾을 수 있습니다: Promise {<resolved>: 정의되지 않음}
그런 다음 Promise 객체의 반환을 표시하고

let p = new Promise((resolve, reject) => setTimeout(() => resolve('p'),1000));
let p1 = new Promise((resolve, reject) => setTimeout(() => resolve('p2'),2000));
let p2 = new Promise((resolve, reject) => setTimeout(() => resolve('p3'),3000));
Promise.all([p, p1, p2]).then(data => console.log(data)).catch(data => console.log(data));    // ["p", "p2", "p2"]

p를 볼 수 있습니다. .then(data => Promise.resolve("Second Promise"))반환된 Promise 객체는 Promise {<resolved promise>이며 값을 다음과 같이 사용합니다. 매개변수를 두 번째 매개변수에 전달한 다음 </resolved>

Promise.resolve(value | promise | thenable)를 실행하여 Promise 객체를 생성합니다
첫 번째 매개변수는 비어 있거나 원래 값이며 생성된 Promise 객체의 상태는 직접 해결 상태입니다

let p = new Promise((resolve, reject) => resolve('p'));
let p1 = new Promise((resolve, reject) => reject('p2'));
let p2 = new Promise((resolve, reject) => resolve('p2'));
Promise.all([p, p1, p2]).then(data => console.log(data)).catch(data => console.log(data));   //p2

두 번째

then 메소드가 포함된

let p = new Promise((resolve, reject) => setTimeout(() => resolve('p'),1000));
let p1 = new Promise((resolve, reject) => setTimeout(() => resolve('p2'),2000));
let p2 = new Promise((resolve, reject) => setTimeout(() => resolve('p3'),3000));
Promise.race([p, p1, p2]).then(data => console.log(data)).catch(data => console.log(data));   //p

Promise 객체 상태가 ->

로 구성된다는 점은 주목할 가치가 있습니다. 세 번째 매개변수는 인스턴스화된 Promise 객체인

setTimeout(function () {
  console.log('three');
}, 0);

Promise.resolve().then(function () {
  console.log('two');
});

console.log('one');

// one
// two
// three
입니다. p 상태는 p1 상태와 일치합니다

Promise.reject(value)는 Promise 객체를 생성합니다

Resolve와 다른 점은 값을 그대로 매개변수로 직접 전달한다는 점입니다.

setTimeout(function() {
  console.log(4)
}, 0);
new Promise(function(resolve) {
  console.log(1);
  for (var i = 0; i < 10000; i++) {
    i == 9999 && resolve()
  }
  console.log(2);
}).then(function() {
  console.log(5)
});
console.log(3);  //1 2 3 5 4

catch 메소드의 매개변수는 " error" 문자열은 거부에 의해 던져졌지만 thenable 객체입니다.

Promise.all

여러 Promise 인스턴스를 새 Promise 인스턴스로 묶습니다. const p = Promise.all([p1, p2, p3]);🎜🎜(1) 모두 p1, p2, p3의 상태만 됩니다. 이행되면 p의 상태가 이행이 됩니다. 이때 p1, p2, p3의 반환 값은 배열을 형성하여 p의 콜백 함수에 전달됩니다. 🎜🎜 (2) p1, p2, p3 중 하나가 거부되는 한 p의 상태는 거부됩니다. 이때 첫 번째 거부된 인스턴스의 반환 값은 p의 콜백 함수에 전달됩니다. 🎜🎜 배열을 콜백 함수에 전달하기 전에 모든 개체가 실행될 때까지 기다린 다음 🎜rrreeerrreee🎜Promise.race🎜 모든 것과의 차이점은 다음과 같습니다. p1, p2, p3 중 하나의 인스턴스가 먼저 상태를 변경하는 한, p's 그에 따라 상태가 변경됩니다. 먼저 변경된 Promise 인스턴스의 반환 값이 p의 콜백 함수에 전달됩니다. 🎜rrreee🎜Promise 객체의 콜백 함수와 setTimeout 사이의 순서 문제🎜

An event loop has one or more task queues. A task queue is an ordered list of tasks, which are algorithms that are responsible for such work as: events, parsing, callbacks, using a resource, reacting to DOM manipulation…Each event loop has a microtask queue. A microtask is a task that is originally to be queued on the microtask queue rather than a task queue.
浏览器(或宿主环境) 遵循队列先进先出原则, 依次遍历macrotask queue中的每一个task, 不过每执行一个macrotask, 并不是立即就执行下一个, 而是执行一遍microtask queue中的任务, 然后切换GUI线程重新渲染或垃圾回收等.
Event Loop (事件循环)拥有如下两种队列
macrotask queue, 指的是宏任务队列, 包括rendering, script(页面脚本), 鼠标, 键盘, 网络请求等事件触发, setTimeout, setInterval, setImmediate(node)等等.
microtask queue, 指的是微任务队列, 用于在浏览器重新渲染前执行, 包含Promise, process.nextTick(node), Object.observe, MutationObserver回调等.
process.nextTick > promise.then > setTimeout ? setImmediate

setTimeout(function () {
  console.log('three');
}, 0);

Promise.resolve().then(function () {
  console.log('two');
});

console.log('one');

// one
// two
// three

上面代码中,setTimeout(fn, 0)在下一轮“事件循环”开始时执行,Promise.resolve()在本轮“事件循环”结束时执行,console.log('one')则是立即执行,因此最先输出。

setTimeout(function() {
  console.log(4)
}, 0);
new Promise(function(resolve) {
  console.log(1);
  for (var i = 0; i < 10000; i++) {
    i == 9999 && resolve()
  }
  console.log(2);
}).then(function() {
  console.log(5)
});
console.log(3);  //1 2 3 5 4

위 내용은 ECMAScript6의 Promise란 무엇입니까? 무슨 소용이 있나요? (예제 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제