JavaScript 基于生成器的异步编程方案相关代码分享

基本的生成器

js 复制代码
// 定义生成器函数
function * foo(){
    console.log("start")
}

// 创建生成器
const generator = foo()

// 调用生成器
generator.next()

生成器的返回值

js 复制代码
// 定义生成器函数
function* foo() {
    console.log("start")

    // 通过 yield 返回内容
    yield "mara"
}

// 创建生成器
const generator = foo()

// 调用生成器
const result = generator.next()
console.log("result=", result)

生成器的参数

js 复制代码
// 定义生成器函数
function* foo() {
    console.log("start")

    // 通过 yield 返回内容
    const arg = yield "mara"
    console.log("arg = ", arg)
}

// 创建生成器
const generator = foo()

// 调用生成器
const result = generator.next()
console.log("result=", result)

// 再调用一次,才能执行到 yield 之后
generator.next("hello")

生成器结合 ajax 使用

js 复制代码
// 模拟 ajax 方法
function ajax(url) {
    return new Promise(function (resolve, reject) {
        const xhr = new XMLHttpRequest()
        xhr.open("GET", url)
        xhr.responseType = "json"
        xhr.onload = function () {
            if (this.status === 200) {
                resolve(this.response)
            } else {
                reject(new Error(this.statusText))
            }
        }
        xhr.send()
    })
}

// 定义生成器函数
function* userRequest() {
    const users = yield ajax("/users.json")
    console.log(users)
}

// 创建生成器
const generator = userRequest()

// 调用生成器
const result = generator.next()

// 进行处理
result.value.then(data => generator.next(data))

多个 ajax 请求

js 复制代码
// 模拟 ajax 方法
function ajax(url) {
    return new Promise(function (resolve, reject) {
        const xhr = new XMLHttpRequest()
        xhr.open("GET", url)
        xhr.responseType = "json"
        xhr.onload = function () {
            if (this.status === 200) {
                resolve(this.response)
            } else {
                reject(new Error(this.statusText))
            }
        }
        xhr.send()
    })
}

// 定义生成器函数
function* userRequest() {
    const users = yield ajax("/users.json")
    console.log(users)

    // 继续发请求
    const urls = yield ajax("/urls.json")
    console.log(urls)
}

// 创建生成器
const generator = userRequest()

// 调用生成器
let result = generator.next()

// 进行处理
result.value.then(data => {
    if (data.done) return

    result = generator.next(data)
    if (result.done) return;

    result.value.then(data=>{
        if (data.done) return
        generator.next()
    })
})

错误处理

js 复制代码
// 模拟 ajax 方法
function ajax(url) {
    return new Promise(function (resolve, reject) {
        const xhr = new XMLHttpRequest()
        xhr.open("GET", url)
        xhr.responseType = "json"
        xhr.onload = function () {
            if (this.status === 200) {
                resolve(this.response)
            } else {
                reject(new Error(this.statusText))
            }
        }
        xhr.send()
    })
}

// 定义生成器函数
function* userRequest() {
    const users = yield ajax("/users.json")
    console.log(users)

    // 继续发请求
    const urls = yield ajax("/urls.json")
    console.log(urls)

    // 发送一个错误的请求
    try{
        const mockError = yield ajax("/urls333.json")
        console.log("mockError", mockError)
    }catch (e){
        console.log("xxx", e)
    }
}

// 创建生成器
const generator = userRequest()

// 调度方法
function handleResult(result) {
    if (result.done) return
    result.value.then(data => {
        handleResult(generator.next(data))
    }).catch(err => generator.throw(err))
}

// 执行调度
handleResult(generator.next())

封装通用的执行器方法

js 复制代码
// 模拟 ajax 方法
function ajax(url) {
    return new Promise(function (resolve, reject) {
        const xhr = new XMLHttpRequest()
        xhr.open("GET", url)
        xhr.responseType = "json"
        xhr.onload = function () {
            if (this.status === 200) {
                resolve(this.response)
            } else {
                reject(new Error(this.statusText))
            }
        }
        xhr.send()
    })
}

// 定义生成器函数
function* userRequest() {
    const users = yield ajax("/users.json")
    console.log(users)

    // 继续发请求
    const urls = yield ajax("/urls.json")
    console.log(urls)

    // 发送一个错误的请求
    try{
        const mockError = yield ajax("/urls333.json")
        console.log("mockError", mockError)
    }catch (e){
        console.log("xxx", e)
    }
}

// 通用的执行器
function co(generator){
    // 创建生成器
    const g = generator()

    // 调度方法
    function handleResult(result) {
        if (result.done) return
        result.value.then(data => {
            handleResult(g.next(data))
        }).catch(err => g.throw(err))
    }

    // 执行调度
    handleResult(g.next())
}

// 调用通用的执行器
co(userRequest)

使用 async 和 await 语法糖

js 复制代码
// 模拟 ajax 方法
function ajax(url) {
    return new Promise(function (resolve, reject) {
        const xhr = new XMLHttpRequest()
        xhr.open("GET", url)
        xhr.responseType = "json"
        xhr.onload = function () {
            if (this.status === 200) {
                resolve(this.response)
            } else {
                reject(new Error(this.statusText))
            }
        }
        xhr.send()
    })
}

// 异步方法
async function userRequest() {
    const users = await ajax("/users.json")
    console.log(users)

    // 继续发请求
    const urls = await ajax("/urls.json")
    console.log(urls)

    // 发送一个错误的请求
    try {
        const mockError = await ajax("/urls333.json")
        console.log("mockError", mockError)
    } catch (e) {
        console.log("xxx", e)
    }
}


userRequest().then(resp => console.log(resp))
    .catch(error => console.log(error))
相关推荐
帅得不敢出门6 小时前
Android Framework定制卸载确认窗口
android
脉动数据行情7 小时前
Java OkHttp 对接国际期货批量行情 SpringBoot 定时落库实践
java·spring boot·okhttp
Android-Flutter8 小时前
Compose 什么叫重组?怎么样触发重组?
android·compose
硫酸锌018 小时前
安卓手机连接Windows电脑后通过DHCP服务为手机分配IP地址
android·windows·计算机网络
VimorphTech8 小时前
React 任务轮询,为什么不能只写一个 setInterval?
javascript·typescript
骑着蜗牛撵大象3278 小时前
设备监控数据存与查:Spring Boot 接入 TimescaleDB 超表的完整落地
android·spring boot·后端·springboot·时序数据库·es·设备监控
lexiangqicheng8 小时前
Docker的沙箱机制是怎样的?
前端·javascript
云贝贝贝8 小时前
MySQL 线上报 Lock wait timeout 别慌:6 招定位锁等待与死锁
android
mmsx9 小时前
Android 签名校验为什么能拦住二次打包:指纹与完整性校验
android·签名
jason.zeng@15022079 小时前
使用vscode+flutter开发android程序(入门)
android·vscode·flutter