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))
相关推荐
霍先生的虚拟宇宙网络4 分钟前
webp 网页如何录屏?
开发语言·前端·javascript
温吞-ing6 分钟前
第十章JavaScript的应用
开发语言·javascript·ecmascript
彪8257 分钟前
第十章 JavaScript的应用 习题
javascript·css·ecmascript·html5
Myli_ing2 小时前
考研倒计时-配色+1
前端·javascript·考研
大白要努力!2 小时前
Android opencv使用Core.hconcat 进行图像拼接
android·opencv
余道各努力,千里自同风2 小时前
前端 vue 如何区分开发环境
前端·javascript·vue.js
PandaCave2 小时前
vue工程运行、构建、引用环境参数学习记录
javascript·vue.js·学习
软件小伟2 小时前
Vue3+element-plus 实现中英文切换(Vue-i18n组件的使用)
前端·javascript·vue.js
醉の虾2 小时前
Vue3 使用v-for 渲染列表数据后更新
前端·javascript·vue.js
张小小大智慧2 小时前
TypeScript 的发展与基本语法
前端·javascript·typescript