async/await связан с родословной Promise

внешний интерфейс JavaScript Promise
async/await связан с родословной Promise

async/await — это решение, предложенное JavaScript для решения проблемы асинхронности, и многие люди называют его окончательным решением проблемы асинхронности. Разработка JavaScript также прошла три этапа: callback, Promise и async/await В этой статье отражено мое собственное понимание async/await. Поскольку использование async/await неотделимо от промисов, если вы не знакомы с промисами, вы можете прочитать это введение:Обещание и его использование в глазах внешнего интерфейса Mengxin.

1. Особые правила использования async/await

Когда мы имеем дело с асинхронностью, метод then из Promise будет лаконичнее и понятнее, чем функция обратного вызова, но при работе с несколькимиКогда другой запрос взаимозависимости, это покажется немного громоздким. В настоящее время более элегантно использовать async и await, которые будут подробно объяснены позже.

Правило использования Async/await 1: любая функция с добавленным впереди async будет автоматически возвращать объект Promise после выполнения.

пример:

async function test() {
    
}

let result = test()
console.log(result)  //即便代码里test函数什么都没返回,我们依然打出了Promise对象

Правило использования Async/await 2: await должен использоваться в асинхронных функциях, а не только

Плохой пример:

function test() {
    let result = await Promise.resolve('success')
    console.log(result)
}

test()   //执行以后会报错

Правильный пример:

async test() {
    let result = await Promise.resolve('success')
    console.log(result)
}
test()

Правило использования Async/await 3: за ожиданием должен следовать объект Promise, в противном случае это бессмысленно, и объект Promise, стоящий за ожиданием, не нужно писать тогда, потому что одна из функций ожиданий заключается в получении параметров, переданных объектом состояние успеха следующего объекта Promise.

Правильный пример:

function fn() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('success')
        })
    })
}

async test() {
    let result = await fn() //因为fn会返回一个Promise对象
    console.log(result)    //这里会打出Promise成功后传递过来的'success'
}

test()

Пример, который не имеет смысла (об ошибке не сообщается):

async test() {
    let result = await 123
    console.log(result)
}

test()

2. Обработка ошибок async/await

Что касается обработки ошибок, как указано в правиле 3, await может напрямую получать параметры, переданные в состоянии успеха промиса, но не может зафиксировать состояние отказа. Здесь мы решаем ее, добавляя методы then/catch к асинхронной функции, которая оборачивает await, потому что согласно правилу 1 асинхронная функция сама возвращает объект Promise.

Полный пример async/await с обработкой ошибок:

let promiseDemo = new Promise((resolve, reject) => {
    setTimeout(() => {
        let random = Math.random()
        if (random >= 0.5) {
            resolve('success')
        } else {
            reject('failed')
        }   
    }, 1000)
})

async function test() {
    let result = await promiseDemo
    return result  //这里的result是promiseDemo成功状态的值,如果失败了,代码就直接跳到下面的catch了
}

test().then(response => {
    console.log(response) 
}).catch(error => {
    console.log(error)
})

В приведенном выше коде необходимо обратить внимание на два момента. Во-первых, асинхронная функция должна активно возвращаться. Если состояние промиса успешное, то возвращаемое значение будет захвачено методом then, описанным ниже; во-вторых, если асинхронная функция функция имеет какие-либо ошибки, все пойманы catch!

3. Синхронный и асинхронный

Если await используется в функции async, код в await станет синхронным, что означает, что он будет продолжаться только после того, как выполнение Обетования await завершено, и результат будет получен. Это также блокирует код, так что используйте его тщательно Отказ

Например следующий код:

function fn(name) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(`${name}成功`)
        }, 1000)
    })
}

async function test() {
    let p1 = await fn('小红')
    let p2 = await fn('小明')
    let p3 = await fn('小华')
    return [p1, p2, p3]
}

test().then(result => {
    console.log(result)
}).catch(result => {
    console.log(result)
})

Хотя это можно написать таким образом, await заблокирует здесь код.Каждое ожидание должно дождаться завершения выполнения следующей fn() перед выполнением следующей строки кода, поэтому тестовая функция выполняется за 3 секунды. Если вы не находитесь в конкретной ситуации, лучше не использовать его таким образом.

3. Небольшой тест

Написав сюда, я вдруг вспомнил, что порядок выполнения кода Promise тоже требует внимания.

Пожалуйста, посмотрите на следующий код, каков порядок чисел, напечатанных после выполнения?

console.log(1)
let promiseDemo = new Promise((resolve, reject) => {
    console.log(2)
    setTimeout(() => {
        let random = Math.random()
        if (random >= 0.2) {
            resolve('success')
            console.log(3)
        } else {
            reject('failed')
            console.log(3)
        }   
    }, 1000)
})

async function test() {
    console.log(4)
    let result = await promiseDemo
    return result
}

test().then(result => {
    console.log(5)
}).catch((result) => {
    console.log(5)
})

console.log(6)

Ответ: 1 2 4 6 3 5

4. Бизнес-сценарий, подходящий для использования async/await

Во внешнем программировании мы иногда сталкиваемся с таким сценарием: нам нужно отправить несколько запросов, иОтправка последующих запросов всегда должна полагаться на данные, возвращенные предыдущим запросом.. Для решения этой проблемы мы можем либо использовать цепочку промисов для ее решения, либо решить ее с помощью async/await, но последнее будет более лаконичным.

Используйте цепочку промисов для обработки:

function request(time) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(time)
        }, time)
    })
}

request(500).then(result => {
    return request(result + 1000)
}).then(result => {
    return request(result + 1000)
}).then(result => {
    console.log(result)
}).catch(error => {
    console.log(error)
}) 

Используйте async/await для обработки:

function request(time) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(time)
        }, time)
    })
}

async function getResult() {
    let p1 = await request(500)
    let p2 = await request(p1 + 1000)
    let p3 = await request(p2 + 1000)
    return p3
}

getResult().then(result => {
    console.log(result)
}).catch(error => {
    console.log(error)
})

Использование async/await значительно читабельнее, чем использование then для сохранения цепочки вызовов.

5. Используйте ожидание в цикле

Если вы используете await в цикле, вам нужно помнить одну вещь:Должен использоваться в асинхронной функции.

существуетfor...ofИспользуйте ожидание в:

let request = (time) => {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve(time)
        }, time)
    })
}

let times = [1000, 500, 2000]
async function test() {
    let result = []
    for (let item of times) {
        let temp = await request(item)
        result.push(temp)
    }
    return result
}

test().then(result => {
    console.log(result)
}).catch(error => {
    console.log(error)
})

Вышеизложенное является записью моего понимания async/await на сегодняшний день.Автор прожил как программист всего полгода.Подсчитано, что в вышеприведенном содержании все еще есть ошибки.Если друзья на наггетсах это увидят,я надеюсь можно указать! Спасибо за просмотр!