[Promise] 알 고 있 습 니 다.
43152 단어 웹 전단
선명 하고 우아 한 코드 를 어떻게 쓰 느 냐 도 디 버 깅 의 중요 한 부분 이다. 과거 오 랜 시간 동안 자 바스 크 립 트 가 가장 토로 하 는 것 은 지옥 (callback hell) 으로 돌아 가 는 것 이다.코드 먼저 보기:
이제 10 문제 로 앞서 배 운 Promise 의 지식 포 인 트 를 공 고 히 하 겠 습 니 다.
제목 1: Promise 구조 함수
const promise = new Promise((resolve, reject) => {
console.log(1)
resolve()
console.log(2)
})
promise.then(() => {
console.log(3)
})
console.log(4)
실행 결과:
1
2
4
3
설명: Promise 구조 함 수 는 동기 적 으로 실 행 됩 니 다. promise. then 의 함 수 는 비동기 적 으로 실 행 됩 니 다.
제목 2: Promise 상태 기
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
}, 1000)
})
const promise2 = promise1.then(() => {
throw new Error('error!!!')
})
console.log('promise1', promise1)
console.log('promise2', promise2)
setTimeout(() => {
console.log('promise1', promise1)
console.log('promise2', promise2)
}, 2000)
실행 결과:
promise1 Promise { }
promise2 Promise { }
(node:50928) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: error!!!
(node:50928) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
promise1 Promise { 'success' }
promise2 Promise {
Error: error!!!
at promise.then (...)
at }
설명: promise 는 3 가지 상태 가 있 습 니 다: pending, fulfilled 또는 rejected.상태 변 화 는 pending - > fulfilled 또는 pending - > rejected 일 수 있 으 며, 상태 가 바 뀌 면 다시 변 할 수 없습니다.위의 promise 2 는 promise 1 이 아니 라 돌아 오 는 새로운 Promise 인 스 턴 스 입 니 다.
제목 3: Promise 상태의 변경 불가
const promise = new Promise((resolve, reject) => {
resolve('success1')
reject('error')
resolve('success2')
})
promise
.then((res) => {
console.log('then: ', res)
})
.catch((err) => {
console.log('catch: ', err)
})
실행 결과:
then: success1
설명: 구조 함수 중의 resolve 나 reject 는 첫 번 째 실행 시 에 만 유효 하 며, 여러 번 호출 하 는 것 은 아무런 역할 이 없 으 며, 코드 2 의 결론 을 다시 한 번 입증 합 니 다: promise 상태 가 바 뀌 면 다시 바 꿀 수 없습니다.
두 가지 예 를 다시 보 자.
const promise = new Promise((resolve, reject) => {
console.log(1)
return Promise.reject(new Error('haha'))
})
promise.then((res) => {
console.log(2, res)
}).catch((err) => {
console.error(3, err)
})
console.log(4)
console.log(promise)
실행 결과:
1
4
Promise { }
(node:22493) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: haha
(node:22493) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
const promise = new Promise((resolve, reject) => {
console.log(1)
throw new Error('haha')
})
promise.then((res) => {
console.log(2, res)
}).catch((err) => {
console.error(3, err)
})
console.log(4)
console.log(promise)
실행 결과:
1
4
Promise {
Error: haha
at Promise (/Users/nswbmw/Desktop/test/app.js:6:9)
...
3 Error: haha
at Promise (/Users/nswbmw/Desktop/test/app.js:6:9)
...
설명: 구조 함수 에 서 는 resolve (pending - > fullfiled) 또는 reject (pending - > rejected) 또는 throw 하나의 error (pending - > rejected) 를 호출 하여 상 태 를 바 꿀 수 있 습 니 다.그래서 첫 번 째 예 의 promise 상 태 는 pending 이 고 'then / catch' 를 호출 하지 않 습 니 다.
제목 4: Promise 체인 호출
Promise.resolve(1)
.then((res) => {
console.log(res)
return 2
})
.catch((err) => {
return 3
})
.then((res) => {
console.log(res)
})
실행 결과:
1
2
설명: promise 는 체인 으로 호출 할 수 있 습 니 다.체인 호출 을 꺼 내 면 우 리 는 보통 return this 를 통 해 이 루어 질 것 이 라 고 생각 하지만 Promise 는 이렇게 이 루어 지지 않 습 니 다.promise 는. then 이나. catch 를 호출 할 때마다 새로운 promise 를 되 돌려 주 고 체인 호출 을 실현 할 수 있 습 니 다.
Axios 는 체인 호출 을 통 해 차단 기 를 실현 하 는 것 이다.원 리 는 다음 과 같다.
/** , promiseRequest */
let requestPromise = function () {
let chain = [{
resolved: () => { console.log('xhr'); return 'xhr'},
rejected: () => 'rejected'
}]
let requestInters = ['request1', 'request2', 'request3']
requestInters.forEach(request => {
chain.unshift({
resolved: () => { console.log(request); return request},
rejected: () => `${err}${request}`
})
})
let responseInters = ['response1', 'response2', 'response3']
responseInters.forEach(response => {
chain.push({
resolved: () => { console.log(response); return response},
rejected: () => `${err}${response}`
})
})
let promise = Promise.resolve('config')
while (chain.length) {
let { resolved, rejected } = chain.shift()
//
promise = promise.then(resolved, rejected)
}
// return promise
// promise.then(resolved1, rejected1).then(resolved2, rejected2).then(resolved2, rejected3).then() ....
return promise
}
requestPromise().then(res => {
console.log(res)
// request3
// request2
// request1
// xhr
// response1
// response2
// response3
// response3
})
제목 5: Promise 내부 상태
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('once')
resolve('success')
}, 1000)
})
const start = Date.now()
promise.then((res) => {
console.log(res, Date.now() - start)
})
promise.then((res) => {
console.log(res, Date.now() - start)
})
실행 결과:
once
success 1005
success 1007
설명: promise 의. then 또는. catch 는 여러 번 호출 될 수 있 지만, 여기 Promise 구조 함 수 는 한 번 만 실 행 됩 니 다.또는 promise 내부 상태 가 바 뀌 고 값 이 있 으 면 나중에 호출 할 때마다. then 또는. catch 에서 이 값 을 직접 받 습 니 다.
이것 은 우리 의 평소 promise 캐 시 에서 매우 유용 합 니 다. 예 를 들 어 app 이 시 작 될 때 promise 를 잠시 저장 할 수 있 습 니 다. 되 돌아 오지 않 을 때 promise 를 다른 호출 자 에 게 직접 주 는 것 이 아니 라 호출 할 때마다 new promise 로 가 는 것 입 니 다.
제목 6: Promise 오류 의 정상 던 지기
Promise.resolve()
.then(() => {
return new Error('error!!!')
})
.then((res) => {
console.log('then: ', res)
})
.catch((err) => {
console.log('catch: ', err)
})
실행 결과:
then: Error: error!!!
at Promise.resolve.then (...)
at ...
설명:. then 또는. catch 에서 return error 대상 은 오 류 를 던 지지 않 기 때문에 후속 적 인. catch 에 포착 되 지 않 습 니 다. 다음 중 하나 로 변경 해 야 합 니 다.
임의의 비 promise 값 을 되 돌려 주면 promise 대상, 즉
return new Error('error!!!')
등가 return Promise.resolve(new Error('error!!!'))
로 감 싸 지기 때문이다.제목 7: Promise 순환 조심
const promise = Promise.resolve()
.then(() => {
return promise
})
promise.catch(console.error)
실행 결과:
TypeError: Chaining cycle detected for promise #
at
at process._tickCallback (internal/process/next_tick.js:188:7)
at Function.Module.runMain (module.js:667:11)
at startup (bootstrap_node.js:187:16)
at bootstrap_node.js:607:3
설명:. then 또는. catch 가 되 돌아 오 는 값 은 promise 자체 일 수 없습니다. 그렇지 않 으 면 순환 을 일 으 킬 수 있 습 니 다.다음 과 유사:
process.nextTick(function tick () {
console.log('tick')
process.nextTick(tick)
})
제목 8: Promise 값 관통 력
Promise.resolve(1)
.then(2)
.then(Promise.resolve(3))
.then(console.log)
실행 결과:
1
설명:. then 또는. catch 의 매개 변 수 는 함수 이 고 비 함수 에 들 어가 면 값 관통 이 발생 합 니 다.
제목 9: Promise 오류 캡 처
Promise.resolve()
.then(function success (res) {
throw new Error('error')
}, function fail1 (e) {
console.error('fail1: ', e)
})
.catch(function fail2 (e) {
console.error('fail2: ', e)
})
실행 결과:
fail2: Error: error
at success (...)
at ...
설명:. then 은 두 개의 인 자 를 받 을 수 있 습 니 다. 첫 번 째 는 성공 적 인 함수 이 고 두 번 째 는 오 류 를 처리 하 는 함수 입 니 다.catch 는. then 두 번 째 매개 변수의 간편 한 쓰기 입 니 다. 그러나 용법 에 있어 서 주의해 야 할 것 이 있 습 니 다. then 의 두 번 째 처리 오류 함수 (fail 1) 는 첫 번 째 처리 성공 함수 (success) 가 던 진 오 류 를 포착 하지 못 하고 후속 적 인. catch 방법 (fail 2) 은 이전의 오 류 를 포착 할 수 있 습 니 다.물론 다음 코드 도 가능 합 니 다.
Promise.resolve()
.then(function success1 (res) {
throw new Error('error')
}, function fail1 (e) {
console.error('fail1: ', e)
})
.then(function success2 (res) {
}, function fail2 (e) {
console.error('fail2: ', e)
})
제목 10: Promise 와 이벤트 순환
Promise.resolve()
.then(() => {
console.log('then')
})
process.nextTick(() => {
console.log('nextTick')
})
setImmediate(() => {
console.log('setImmediate')
})
console.log('end')
실행 결과:
end
nextTick
then
setImmediate
설명:
process.nextTick
과 promise.then
는 모두 microtask (그러나 process. nextTick 의 우선 순 위 는 promise. then 보다 크다) 에 속 하고 setImmediate 는 macrotask 에 속 하 며 이벤트 순환 의 check 단계 에서 실 행 됩 니 다.이벤트 순환 의 모든 단계 (macrotask) 간 에 microtask 를 실행 합 니 다. 상기 코드 자체 (macrotask) 는 실행 이 끝 난 후에 microtask 를 한 번 실행 합 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
js div 드래그 호 환 i / fireforx js 마우스 위치 깊이 분석이벤트 속성 은 이벤트 가 실 행 될 때 브 라 우 저 페이지 (클 라 이언 트) 에 대한 수직 좌 표를 되 돌려 줍 니 다. 이 두 속성 은 이벤트 가 실 행 될 때 마우스 포인터 가 브 라 우 저 페이지 (클 라...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.