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))
相关推荐
赏金术士2 小时前
Kotlin 习题集 · 高级篇
android·开发语言·kotlin
问心无愧05134 小时前
ctf show web 入门42
android·前端·android studio
没什么本事4 小时前
关于C# panel 添加lable问题 -- 明确X和Y 位置错误
android·java·c#
张元清6 小时前
React Observer Hooks:7 种监听 DOM 而不写样板代码的方式
前端·javascript·面试
竹林8186 小时前
Next.js + wagmi v2 踩坑实录:开发 NFT 交易市场时,我如何处理离线签名和链下元数据
javascript·next.js
前端Hardy6 小时前
谁还没⽤过shadcn/ui?114k+星标,不装NPM包,前端组件自由终于实现了
前端·javascript·vue.js
猪猪聪明_V7 小时前
前端码农的本地项目启动器
前端·javascript
暗不需求7 小时前
前端性能优化 防抖与节流完全指南:从原理到最佳实践
前端·javascript·面试
@大迁世界7 小时前
45.什么是内联条件表达式(inline conditional expressions)?在事件处理里怎么用?
开发语言·前端·javascript·react.js·ecmascript
我胖虎不答应!!7 小时前
Three.js开发思想笔记
javascript·笔记·three.js