>  기사  >  웹 프론트엔드  >  약속 이해, 비동기, 대기

약속 이해, 비동기, 대기

hzc
hzc앞으로
2020-07-04 09:50:021867검색

이전 글에서는 주로 동기화와 비동기성, '실행 스택', '메시지 큐', 그리고 각각에서 파생되는 '매크로 태스크'와 '마이크로 태스크'에 대해 이야기했습니다. 이해하세요. 다음 링크로 이동할 수 있습니다:

https://www.jianshu.com/p/61e7844e68d8

Ajax 요청, 타이머 등을 포함하여 매크로 작업과 마이크로 작업은 모두 비동기식입니다. Promise에 대해 미리 살펴보겠습니다. , 비동기 문제를 해결하는 방법이라는 것을 알면서 우리가 일반적으로 사용하는 방법은 무엇입니까?

많은 지식 포인트가 포함되어 있기 때문에 이 기사에서는 주로 콜백 함수와 약속에 대해 설명합니다.

一, 콜백 함수

先上代码:
function f2() {
    console.log('2222')
}
function f1(callback){
    console.log('111')
  setTimeout(function () {
    callback(); 
  }, 5000);
  console.log('3333')
}
f1(f2);

先看下打印值是:
111
3333
五秒后2222

는 메인 스레드가 실행을 종료하는 것과 동일하며 콜백 함수를 통해 f2 함수가 호출됩니다. 이는 아무런 문제가 없습니다. 그런데 아래 예를 보세요.

现在我们读取一个文件,fileReader就是一个异步请求

// 这个异步请求就是通过回调函数的方式获取的

var reader = new FileReader()
var file = input.files[0]
reader.readAsText(file, 'utf-8',function(err, data){
    if(err){
        console.log(err)
    } else {
        console.log(data)
    }
})

지금은 매우 좋아 보이지만 파일 업로드에 오류가 있으면 콜백에서 판단해야 합니다. 이 파일 읽기를 마친 다음 여러 파일을 읽으면 어떻게 될까요? 이렇게 작성해야 할까요?

读取完文件1之后再接着读取文件2、3

var reader = new FileReader()
var file = input.files[0]
reader.readAsText(file1, 'utf-8',function(err1, data1){
    if(err1){
        console.log(err1)
    } else {
        console.log(data1)
    }
    reader.readAsText(file2, 'utf-8',function(err2, data2){
        if(err2){
            console.log(err2)
        } else {
            console.log(data2)
        }
        reader.readAsText(file3, 'utf-8',function(err3, data3){
            if(err3){
                console.log(err3)
            } else {
                console.log(data3)
            }
        })
    })
})

이렇게 작성하면 요구 사항을 충족할 수 있지만 이 코드의 가독성이 상대적으로 떨어지고 우아해 보이지도 않는데, 이를 흔히 '콜백 지옥'이라고 부릅니다. 그렇다면 이 중첩된 콜백을 해독하는 방법은 무엇입니까? ES6는 우리에게 약속을 제공합니다:

2. 약속

먼저, 약속이 문자 그대로 무엇인지 이해합시다. 약속은 약속과 보증으로 해석될 수 있습니다.

내 여자친구가 나에게 뭔가를 해달라고 요청했습니다. 아직 완료하지 않았지만 이 문제가 성공할 것이라고 약속합니다. ) 또는 실패(거부)되어 대기 상태(보류)가 있습니다.

还是先上例子

let promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(2000) // 成功以后这个resolve会把成功的结果捕捉到
        // reject(2000) // 失败以后这个reject会把失败的结果捕捉到
    }, 1000)
    console.log(1111)
})

promise.then(res => {
    console.log(res) // then里面第一个参数就能拿到捕捉到的成功结果
}, err =>{
    console.log(res)// then里面第二个参数就能拿到捕捉到的失败结果
})

打印结果:

1111
2000(一秒以后)

1. Then 체인 연산

Promise 객체의 then 메소드는 새로운 Promise 객체를 반환하므로 체인을 통해 then 메소드를 호출할 수 있습니다.

Then 메서드는 두 가지 함수를 매개변수로 받습니다. 첫 번째 매개변수는 Promise가 성공적으로 실행될 때의 콜백입니다. 위의 예에서 캡처하는 두 번째 매개변수는 실패한 콜백입니다. .

두 함수 중 하나만 호출됩니다. 이 문장을 어떻게 이해하시나요?
여자친구가 토마토 계란 수프를 만들어 달라고 합니다. 당신이 하든 안 하든 테이크아웃을 하세요.

함수의 반환 값은 그때 반환되는 Promise 객체를 생성하는 데 사용됩니다. 이 문장은 어떻게 이해해야 할까요? 위의 예는 다음과 같습니다.

let promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(2000)
    }, 1000)
    console.log(1111)
})
promise.then(res => {
    console.log(res) // 这个地方会打印捕捉到的2000
    return res + 1000 // 这个函数的返回值,返回的就是这个promise对象捕捉到的成功的值
}).then(res => {
    console.log(res) //这个地方打印的就是上一个promise对象return的值
})

所以打印顺序应该是:

1111
2000
3000

방금 then이 두 개의 매개변수를 허용하는 것을 보았습니다. 하나는 성공 콜백이고 다른 하나는 실패 콜백입니다. then 외에도 promise는 catch 메소드를 제공합니다. :

2, catch 캡처 작업

이 catch는 오류 콜백을 캡처하도록 특별히 설계되었습니다. 먼저 예제를 살펴보겠습니다.

let promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject(2000) // 失败以后这个reject会把失败的结果捕捉到
    }, 1000)
    console.log(1111)
})
promise.catch(res => {
    console.log(res) // catch里面就能拿到捕捉到的失败结果
})

打印结果:

1111
2000(一秒以后)

then과 catch 외에도 promise에는 all과 race라는 두 가지 구문이 있습니다. 간략하게:

3. all

이제 이러한 요구 사항이 있습니다. 세 가지 인터페이스 A, B, C가 있습니다. 네 번째 요청은 세 가지 인터페이스가 모두 성공한 후에만 시작될 수 있습니다.

연속 호출

let getInfoA = new Promise((resolve, reject) => {
    console.log('小A开始执行了')
    resolve()
}).then(res => {
    let getInfoB = new Promise((resolve, reject) => {
        console.log('小B开始执行了')
        resolve()
    }).then(res => {
        let getInfoC = new Promise((resolve, reject) => {
            console.log('小C开始执行了')
            resolve()
        }).then(res => {
            console.log('全都执行完了!')
        })
    })
})

계층이 하나씩 이어져 있어서 그다지 우아해 보이지는 않습니다

all

let getInfoA = new Promise((resolve, reject) => {
    console.log('小A开始执行了')
    resolve()
})
let getInfoB = new Promise((resolve, reject) => {
    console.log('小B开始执行了')
    resolve()
})
let getInfoC = new Promise((resolve, reject) => {
    console.log('小C开始执行了')
    resolve()
})
Promise.all([getInfoA, getInfoB, getInfoC]).then(res => {
   console.log('全都执行完了!')
})

Promise 객체의 배열을 매개변수로 받습니다. 이 배열에 있는 모든 Promise 객체의 상태가 해결되거나 거부될 때. , then 메소드를 호출합니다. 너무 완벽하고, 너무 우아해요.

4. Race

이제 인터페이스 A, B, C인 또 다른 요구 사항이 있습니다. 둘 중 하나가 응답하는 한 인터페이스 D를 조정할 수 있습니다. 그러면 어떻게 구현할까요?

1. 전통적인 방식

let getInfoA = new Promise((resolve, reject) => {
    console.log('小A开始执行了')
    setTimeout((err => {
        resolve('小A最快')
    }),1000)
}).then(res =>{
    console.log(res)
})
let getInfoB = new Promise((resolve, reject) => {
    console.log('小B开始执行了')
    setTimeout((err => {
        resolve('小B最快')
    }),1001)
}).then(res =>{
    console.log(res)
})
let getInfoC = new Promise((resolve, reject) => {
    console.log('小C开始执行了')
    setTimeout((err => {
        resolve('小C最快')
    }),1002)
}).then(res =>{
    console.log(res)
})

打印结果

小A开始执行了
小B开始执行了
小C开始执行了
小A最快

이 방식은 세번을 작성해야 하는데 그리 우아해 보이지는 않네요.

2. race

let getInfoA = new Promise((resolve, reject) => {
    console.log('小A开始执行了')
    setTimeout((err => {
        resolve('小A最快')
    }),1000)
})
let getInfoB = new Promise((resolve, reject) => {
    console.log('小B开始执行了')
    setTimeout((err => {
        resolve('小B最快')
    }),1001)
})
let getInfoC = new Promise((resolve, reject) => {
    console.log('小C开始执行了')
    setTimeout((err => {
        resolve('小C最快')
    }),1002)
})
Promise.race([getInfoA, getInfoB, getInfoC]).then(res => {
    console.log(res)
})

打印结果

小A开始执行了
小B开始执行了
小C开始执行了
小A最快

Promise.all과 유사하게 Promise.race는 Promise 객체의 배열을 매개변수로 사용합니다. 차이점은 배열의 Promsie 상태 중 하나가 해결되거나 거부되는 한 다음을 호출할 수 있다는 것입니다. .then 메소드.

Promise는 ES6에서 비동기 문제를 해결하기 위해 사용하는 방법입니다. 예를 들어 우리가 자주 사용하는 axios는 promise로 캡슐화되어 있어 사용하기 매우 편리합니다.

Promise 외에도 ES6는 async 및 Wait에 대한 궁극적인 트릭을 제공합니다. 이 두 가지 지식 블록은 상대적으로 크기 때문에 다음 기사에서 이에 대해 이야기하겠습니다.

개인 WeChat 공개 계정: Jerry는 할 말이 있으면 주로 기술 관련 기사와 독서 노트를 게시합니다.

추천 튜토리얼: "JS Tutorial"

위 내용은 약속 이해, 비동기, 대기의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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