비동기식 - 대기 중
33295 단어 programmingjavascript
비동기식 대기 키워드
이것은 코드에 어떤 영향을 미치고 표준 자바스크립트의 약속에 비해 어떤 영향을 미치는가.
그리고 두 가지 예시를 통해Promise를 사용할 때 코드의 외관과 async await 키를 사용할 때 코드의 외관을 보여 드리겠습니다.
이 두 가지 인코딩 스타일을 사용할 때, 나는 함정과 까다로운 부분을 언급할 것이다.
관련 문서와 규범에 대한 링크를 드리겠습니다.
소개하다.
Async-await는 비동기 흐름을 간소화하기 위해 2017년에 Ecmascript 규범을 도입했다.
기본 원칙과 규칙
비동기 함수는 다음과 같이 키워드 async로 정의됩니다.
async myFunction() {
// body of the function
}
비동기 스타일 함수에 대한 서명은 다음과 같습니다.([...any]): Promise<any>
async 함수는 어느 곳에서든 호출할 수 있지만, async 블록에서만 await 키워드를 사용할 수 있습니다.async myFirstFunction() {
// some logic
const partial = await getParialResult(); // calling another async function or function returning promise
// other logic
return processPartial(partial) // calling sync function with non promise parameter returning non promise value
}
부분some logic
은 동기화되어 실행되었다.부분other logic
비동기 함수 호출 getParial Result 가 해결되었습니다.약속과의 관계
표준 함수와 비동기 함수의 차이는 비동기 함수가 항상 자바스크립트
Promise
대상을 되돌려준다는 데 있다.이 점에 관해서는 거의 아무런 기본 규칙이 없다.
정의되지 않은return문
그 중에서 표준 함수 반환
undefined
값, 비동기 함수 반환Promise<undefined>
-공약 해석undefined
.async myFunction() {
console.log('hi from async function')
}
함수 반환(편집 불가) 값
만약return문장이 존재하고 반환값이 a
Promise
와 notundefined
가 아니라면 이 값은 해석된 Promise
문장에 포장됩니다그리고 돌아왔습니다.
async function myFunction() {
...
return 'hello world'
}
myFunction() // Promise { 'hello world' }
이와 유사한 동작은 다음과 같습니다.function myFunction() {
return Promise.resolve('hello world')
}
함수 반환 테이블 값promise 또는promise-like 대상
마지막 사례는 이전 사례의 자집에 불과하지만 특별히 언급할 만하다.
비동기 함수가 Promise를 반환합니다.이런 상황에서 통역사는 다시 비슷한 일을 하지만 미묘하지만 중요한 차이가 있다.
[thenable] 객체가 발견되면 내포된 레이어가 자동으로 벤드펴집니다.이것은 비동기 함수가 되돌아오는 상황이 아니다.여기서 프로미스에서 포장된 값이 전개되어 새로운 프로미스 대상에 다시 포장됩니다.
약속에 비하다.결심:
const myPromise = new Promise((resolve, reject) => { resolve(42) });
async function myAsyncFunction() { return myPromise }
var p = myFunction()
// p is holding Promise { 42 }
p === myPromise // false
myPromise === Promise.resolve(myPromise) // true, because the nested structure is flattened
표준 기능과 비교:function mySyncFunction() { return myPromise }
var p = myFunction()
// p is holding Promise { 42 }
p === myPromise // true
비동기 함수에서 해석 약속이 포함된 값을 반환하는 동작을 시뮬레이션하면 다음과 같이 작성할 수 있습니다.function likeAsyncFunction() {
// value inside promise is unwrapped and wrapped again in new promise object
return myPromise.then(value => Promise.resolve(value))
}
p = likeAsyncFunction() // Promise { 42 }
myPromise === p // false
그럼, 그것은 단지 문법상의 설탕일 뿐입니까?
내가 가장 먼저 생각한 것은 견지하는 것이다. 이것은 단지 약속한 문법적 당분일 뿐이다.
Promise.resolve
키워드 뒤에 존재하는 모든 내용을 await
프로세서에 들어갈 수 있습니다.이거 진짜예요?약속의 유사성과 차이를 설명할 수 있는 예는 드물다. 약속 이외의 이종 대기 구조를 어떻게 탐색할 수 있는지에 대한 생각이나 개념을 줄 수도 있다.
동기와 비동기 부분
나는 아래의 예시에서 전형적인 비동기 함수의 성질을 설명할 것이다.이것은 nodejs에서 실행할 수 있습니다.
// app.js
// run node app.ja
/*
* this function will be used trhought few more examples, so keep it.
* when using plain promises the async keyword can be ignored (ref. to the above explanation)
*/
async function sleep(mls) {
return new Promise((resolve) => {
setTimeout(() => {
console.log('resolving...')
resolve(mls)
}, mls)
})
}
async function serviceB() {
console.log('serviceB:1');
await sleep(1000)
console.log('serviceB:2')
}
async function serviceA() {
console.log('serviceA:1')
await serviceB()
console.log('serviceA:2')
}
console.log('before')
serviceA();
console.log('after')
상기 코드는 다음과 같은 출력을 생성할 것이다before
serviceA:1
serviceB:1
after
resolving...
serviceB:2
serviceA:2
서비스A가 일반 함수로 호출되었습니다.동기화를 계속합니다.서비스 A 내부에서 서비스 B에 대한 함수 호출을 통해 첫 번째wait 키워드를 얻을 수 있습니다.현재 이 함수 서비스 B를 분석하고 실행합니다.
반환 (Promise) 이나 다른 대기 함수 호출을 찾을 때까지 창고로 전송되고 동기화됩니다.
호출을 기다린 후 함수의 나머지 부분에 무슨 일이 일어났습니까?
그것은 리셋과 유사한 또 다른 코드 블록으로 여겨진다.비동기식 작업이 완료되면 블록은 대기열에 서서 스택으로 돌아갑니다.
이것은 사용 승낙에 매우 가까운 등가물이다.
function serviceB() {
console.log('serviceB:1');
return new Promise(resolve => {
sleep(1000).then(() => {
console.log('serviceB:2')
resolve();
})
})
}
function serviceA() {
console.log('serviceA:1')
return new Promise((resolve) => {
serviceB().then(() => {
console.log('serviceA:2')
resolve();
})
})
}
console.log('before')
serviceA();
console.log('after')
이전 코드와 완전히 같은 방식으로 실행하면 완전히 같은 출력이 발생합니다.콘솔 로그 프레젠테이션함수 서비스A와 서비스B가 창고에 도착하면 창고에서 실행할 수 있도록 합니다
then
.비동기적인 부분이 완성되면 리셋 또는 비동기적인 코드 블록을 창고에 놓고 서비스B를 실행하고 리셋 또는 비동기적인 코드 블록을 창고에 놓고 서비스A를 실행합니다.
그것이 어떻게 작동하는지 제외하고 이 두 가지 예는 앞에서 언급한 비동기 대기 구조의 장점 중 하나를 보여 준다.
코드의 가독성이 더욱 높고, 리셋도 그다지 어지럽지 않다.
그러나 어떤 사람들은 문법의 동기성이 혼란을 일으킬 수 있고 일부 오류는 추적하기 어렵다고 생각할 수도 있다.
나 이게 무슨 뜻이야?
serviceA()
serviceB()
serviceC()
만약 이것들이 내부에wait가 있는 비동기 함수라면 함수의wait 부분에서 완성된 순서는 이 함수를 호출하는 순서와 무관하다.전통적인 방식으로 이 글을 쓰면 실제 행위를 더욱 촉진시킬 수 있다.
serviceA().then(callbackA)
serviceB().then(callbackB)
serviceC().then(callbackC)
장래의 곤혹을 피하기 위해서 사물이 어떻게 작동하는지 배우는 것은 항상 좋다.순환 및 유사
for 순환에서 비동기 코드를 처리합니다. 특히 리셋이 순서대로 실행되어야 할 때 어려울 수 있습니다.
사용
console.log('after')
시 간단명료하게 보임async function update(earliestVersion, lastVersion)
{
for (i = earliestVersion; i <= lastVersion, i++) {
try {
await applyUpdate(`version_${first}`);
} catch(e) {
throw Error('Update Error')
}
}
}
// possible usage in the code:
update(12, 16)
.then(handleSuccess)
.catch(handleError)
.finally(handleFinish)
약속에 기초한 대체 방안이 비슷한 역할을 할 수도 있다.논리가 어떻게 흐르는지 아직 잘 모르며, 어디에 있는지, 이상과 고장을 어떻게 처리하는지는 말할 것도 없습니다.
function update(earliestVersion, lastVersion) {
function _update(version){
return applyUpdate(version)
.then((res) => {
if (version <= lastVersion) {
return _update(version + 1)
} else {
return res;
}
})
.catch(() => { throw Error('Update Error') })
}
return _update(version)
}
WHILE loop과 비슷한 거.
이것은 for 순환의 상황과 유사하다.만약 우리가 풍전장 중심을 운행하고 있다면 서버는 풍력 터빈의 상태를 보고해야 한다.
열악한 날씨 상황에서 서버는 이 상태를 검색하거나 최대 시도 횟수에 도달할 때까지 풍력 터빈의 상태를 계속 물어봐야 한다.
async function reportStatus(nu) {
let status = false;
let tries = 0;
while (!status) {
await status = getTurbineStatus(nu)
logStatusCall(no, status, tries++)
}
return status;
}
// usage
turbines.forEach(reportStatus)
// or
Promses.allSettled(turbines.map(reportStatus))
.then(handleResponses)
for-loop과 유사하게 공약을 사용하여 작성하고 테스트하는 것은 더욱 도전적일 것이다function reportStatus(nu) {
let status = false;
let tries = 0;
function _helper(n){
return getTurbineStatus(n).then((status) => {
logStatusCall(no, status, tries++)
if (!status) {
return _helper(n);
} else {
return status
}
})
}
return _helper(nu)
}
발전기의 기능은 어떻습니까?
생성기 함수와 async 키워드를 조합할 수 있습니까?어느 정도 옳고 그름.
다음은 간단한 카운트다운 함수의 예이다.setTimeout을 사용하고 있습니다.
async function* countdown(count, time) {
let index = count;
while (index) {
await sleep(time)
yield --index;
}
}
async function testCountDown(count) {
const cd = countdown(4, 1000)
let val = await cd.next();
while (!val.done) {
console.log(`finish in ${val.value}`)
val = await cd.next();
}
console.log('...finished')
}
testCountDown(5)
동기 발전기의 기능과 비교하면 관건적인 차이가 있다.그것은 사실상 교체 프로토콜을 파괴했다.비동기 함수는 항상 약속을 되돌려주기 때문에 예상 대상
async-await
은 약속에 포장됩니다.그것도
{ value, done }
순환에 적용되지 않고 확장 연산자for..of
에도 적용되지 않는다.이 두 가지 구조는 모두
[...iterable]
가 필요하지만 해석기는 직접 접근할 수 없다iterable
대상.나의 조언은 async generator 함수를 사용하지 않는 것이다. 만약 정말 그것을 사용해야 한다면, 그것들 사이의 차이를 주의하여 의외의 행위와 오류를 피하십시오.
비동기 함수를 일종의 방법으로 삼다
방법은 대상에 귀속된 함수다.그렇다면 비동기 함수는 하나의 방법으로서 어떻게 일을 하는가, 전통 함수에 비해 어떻게 일을 하는가?
비동기 함수도 이곳의 절차를 간소화시켰다.promise handler의 promise와 달리 키워드
{ value, done }
는 호출 대상을 가리키며 this
키워드 뒤에 있는 블록의 비동기적인 부분을 가리킨다.promise 프로세서 내부에서 인용하기 await
는 화살표 함수나 귀속 this
을 사용해야 합니다.예:
function logName() {
console.log(`Hi, my name is ${this.name}.`)
}
class Simpson {
constructor(name) {
this.name = name
}
logName() {
console.log(`Hi, my name is ${this.name}.`)
}
async waitAndSayHi(time) {
await sleep(time);
this.logName();
}
waitAndSayHiWithPromise(time) {
return new Promise(resolve => {
sleep(time).then(this.logName.bind(this))
})
}
}
const lisa = new Simpson('Lisa')
const bart = new Simpson('Bart')
lisa.waitAndSayHi(500)
bart.waitAndSayHiWithPromise(1000)
생략this
은 뚜렷한 오류를 초래하고 원인이 뚜렷하다..bind(this)
를 사용할 때 우리는 걱정할 필요가 없는 일이다.요약
async-await는 비동기 코드를 처리하는 간편한 방법이다.그것은 흐름 제어에 도움이 되며, 여러 개의 비동기 조작 서열이 필요한 순환에 특히 유용하다.
만약 프로그래머가 결과를 충분히 의식한다면, 그것은 코드의 가독성을 높일 수 있다.
그것은 약속의 문법사탕이 아니라 약속 구조의 확장으로 여겨져야 한다.
출처
Reference
이 문제에 관하여(비동기식 - 대기 중), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/webduvet/async-await-412j텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)