ES6-ES11-第一部分-let、const、解构赋值、模板字符串、简化对象写法、箭头函数、函数参数默认值、rest 参数、扩展运算符、Symbol、迭代器、生成器、Promise、Set、Map(五)

简介: ES6-ES11-第一部分-let、const、解构赋值、模板字符串、简化对象写法、箭头函数、函数参数默认值、rest 参数、扩展运算符、Symbol、迭代器、生成器、Promise、Set、Map(五)

12.4 生成器函数实例 - 2

// 模拟 先获取用户数据,获取用户的订单信息,获取订单的商品数据
      function getUsers() {
        setTimeout(() => {
          let user = '用户数据'
          // 第一个片段的数据传给第二个片段
          // 调用第二个next并传参
          // 相当于第一个yield返回值
          i.next(user) 
        }, 1000)
      }
      function getOrders( users ) {
        console.log(users)
        setTimeout(() => {
          let order = '订单信息'
          i.next(order)
        }, 1000)
      }
      function getGoods( orders ) {
        console.log(orders)
        setTimeout(() => {
          let good = '商品数据'
          i.next(good)
        }, 1000)
      }
      // 声明生成器函数
      function * gen() {
        let users = yield getUsers()
        let orders = yield getOrders(users)
        let goods = yield getGoods( orders )
        console.log(goods)
      }
      // 迭代器对象
      let i = gen()
      i.next()

13. Promise

【Promise(简介、基本使用、API、手写实现 Promise、async与await)】

Promise 是 ES6 引入的异步编程的新解决方案。(解决回调地狱)

语法上 Promise 是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。

13.1 Promise 基本使用

// 创建一个Promise对象,Promise对象有三个状态
      // 刚实例的promise对象的状态为pending
      // 需要传入一个参数,参数为函数
      // 函数需要两个参数,一个为成功的函数,可以将promise的状态改为成功
      // 另一个参数为失败的函数,可以将promise的状态改为失败
      const p1 = new Promise((resolve, reject) => {
        // 成功
        let data = '数据中的数据'
        resolve(data)
      })
      // promise对象可以通过then指定成功和失败的回调函数
      // 第一个参数为成功的回调函数
      // 第二个参数为失败的回调函数
      p1.then(
        (value) => {
          console.log(value)
        },
        (reason) => {
          console.log(reason)
        }
      )
      const p2 = new Promise((resolve, reject) => {
        // 失败
        let data = '从数据库获取数据失败'
        reject(data)
      })
      p2.then(
        (value) => {
          console.log(value)
        },
        (reason) => {
          console.log(reason)
        }
      )

13.2 Promise 封装读取文件

使用 js 读取文件要在 Node.js 环境下

fs模块读取文件:

// 导入fs模块
const fs = require('fs')
// 读取文件
// 第一个参数为读取文件的路径
// 第二个参数为回调函数(回调函数第一个参数为失败的对象,第二个参数为读取到的数据)
fs.readFile('./00-文本文件.txt', (err, data) => {
  if (err) console.log(err)
  console.log(data.toString())
})

使用Promise封装fs读取文件:

const p = new Promise((resolve, reject) => {
  fs.readFile('./00-文本文件.txt', (err, data) => {
    if (err) reject(err)
    resolve(data.toString())
  })
})
p.then(value => {
  console.log(value)
}, reason => {
  console.log(reason)
})

13.3 Promise 封装AJAX

原生AJAX:

<body>
  <script>
    // 原生AJAX
    // 创建发送AJAX请求的对象
    const xhr = new XMLHttpRequest()
    // 初始化请求对象
    xhr.open('GET', 'http://127.0.0.1:8000')
    // 设置请求头
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
    // 发送请求
    xhr.send()
    // 处理请求响应回来的数据
    xhr.onreadystatechange = function() {
      if (xhr.readyState === 4) {
        if ( xhr.status>=200 && xhr.status<300 ) {
          console.log(xhr.response) // 打印响应回来的数据
        }
      }
    }
  </script>
</body>

服务端代码:

// 导入express
const express = require('express')
// 创建应用对象
const app = express()
// 创建路由对象
// request 是对请求报文的封装
// response 是对响应报文的封装
app.get('/', (request, response) => {
  //设置响应头  设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*');
  // 向客户端发送数据
  response.send('Hello AJAX')
})
app.post('/', (request, response) => {
  //设置响应头  设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*');
  response.setHeader('Access-Control-Allow-Headers', '*');
  response.setHeader('Access-Control-Allow-Methods', '*');
  response.setHeader('Access-Control-Expose-Headers', '*');
  // 向客户端发送数据
  response.send('Hello AJAX POST')
})
// 启动服务器进行监听
// 8000 端口 服务端在8000端口监听客户端向8000端口发送过来的请求
app.listen(8000, () => {
  console.log('服务端在8000端口监听')
})

使用Promise封装:

<body>
    <script>
      const p = new Promise((resolve, reject) => {
        // 创建发送AJAX请求的对象
        const xhr = new XMLHttpRequest()
        // 初始化请求对象
        xhr.open('GET', 'http://127.0.0.1:8000')
        // 设置请求头
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
        // 发送请求
        xhr.send()
        // 处理请求响应回来的数据
        xhr.onreadystatechange = function () {
          if (xhr.readyState === 4) {
            if (xhr.status >= 200 && xhr.status < 300) {
              // 成功
              resolve(xhr.response)
            } else {
              // 失败
              reject(xhr.status)
            }
          }
        }
      })
      // 回调
      p.then(
        (value) => {
          console.log(value)
        },
        (reason) => {
          console.log(reason)
        }
      )
    </script>
  </body>

13.4 Promise.prototype.then()

Promise.prototype.then()的返回结果也为一个Promise对象。

const p1 = new Promise((resolve, reject)=>{
      setTimeout(()=>{
        resolve('用户数据')
      },1000)
    })
    const res1 = p1.then(v=>{
      console.log(v)
    }, r=>{
      console.log(r)
    })
    console.log(res1)

fulfilled表示成功的状态

then()返回的Promise对象的状态由回调函数的执行结果决定。

  1. 如果回调函数中返回的结果是 非 promise 类型的属性, 状态为成功, 返回值为对象的成功的值
const p1 = new Promise((resolve, reject)=>{
      setTimeout(()=>{
        resolve('用户数据')
      },1000)
    })
    const res1 = p1.then(v=>{
      // console.log(v)
      return 123
    }, r=>{
      console.log(r)
    })
    console.log(res1)

  1. 是 promise 对象,返回的Promise对象的状态由return的Promise对象的状态决定,返回的Promise对象的结果,为return的promise对象的结果
const p1 = new Promise((resolve, reject)=>{
      setTimeout(()=>{
        resolve('用户数据')
      },1000)
    })
    const res1 = p1.then(v=>{
      // console.log(v)
      return new Promise((reso, reje)=>{
        reso()
      })
    }, r=>{
      console.log(r)
    })
    console.log(res1)

const p1 = new Promise((resolve, reject)=>{
      setTimeout(()=>{
        resolve('用户数据')
      },1000)
    })
    const res1 = p1.then(v=>{
      // console.log(v)
      return new Promise((reso, reje)=>{
        reje('ERRor')
      })
    }, r=>{
      console.log(r)
    })
    console.log(res1)

rejected表示失败的状态

  1. 抛出错误,返回的为失败状态的promise对象,错误信息为返回的promise对象的结果
const p1 = new Promise((resolve, reject)=>{
      setTimeout(()=>{
        resolve('用户数据')
      },1000)
    })
    const res1 = p1.then(v=>{
      // console.log(v)
      throw 'ERROR'
    }, r=>{
      console.log(r)
    })
    console.log(res1)

由于then返回的为promise对象,所以promise可以链式调用:

//链式调用
p.then(value=>{
}).then(value=>{
});

链式调用可以解决回调地狱。

相关文章
【Java每日一题,Map和字符串】Ananagrams
【Java每日一题,Map和字符串】Ananagrams
|
5月前
|
前端开发 安全
协程问题之协程函数返回的Promise对象必须满足哪些要求
协程问题之协程函数返回的Promise对象必须满足哪些要求
|
4月前
|
前端开发
手写实现ES6的Promise.all()和Promise.race()函数
这篇文章介绍了如何手写实现ES6的`Promise.all()`和`Promise.race()`函数,提供了实现这两个Promise聚合函数的详细代码示例,并展示了如何使用它们。
手写实现ES6的Promise.all()和Promise.race()函数
|
7月前
|
Go
|
7月前
|
算法 测试技术 C#
【map】【滑动窗口】【字典树】C++算法:最长合法子字符串的长度
【map】【滑动窗口】【字典树】C++算法:最长合法子字符串的长度
|
7月前
|
前端开发
箭头函数与promise
箭头函数与promise
47 0
|
JSON 数据格式
JSON字符串与Map互转
JSON字符串与Map互转
409 0
|
设计模式 JSON 前端开发
前端面试必看(手写Promise+js设计模式+继承+函数柯里化等)JavaScript面试全通关(1/3)
前端面试必看(手写Promise+js设计模式+继承+函数柯里化等)JavaScript面试全通关(1/3)
78 0
|
前端开发
前端学习笔记202306学习笔记第四十二天-函数返回promise
前端学习笔记202306学习笔记第四十二天-函数返回promise
44 0
|
前端开发 API 网络架构
ES6-ES11-第一部分-let、const、解构赋值、模板字符串、简化对象写法、箭头函数、函数参数默认值、rest 参数、扩展运算符、Symbol、迭代器、生成器、Promise、Set、Map(六)
ES6-ES11-第一部分-let、const、解构赋值、模板字符串、简化对象写法、箭头函数、函数参数默认值、rest 参数、扩展运算符、Symbol、迭代器、生成器、Promise、Set、Map(六)