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=>{
});

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

相关文章
|
6天前
|
存储 JavaScript 前端开发
JavaScript进阶-Map与Set集合
【6月更文挑战第20天】JavaScript的ES6引入了`Map`和`Set`,它们是高效处理集合数据的工具。`Map`允许任何类型的键,提供唯一键值对;`Set`存储唯一值。使用`Map`时,注意键可以非字符串,用`has`检查键存在。`Set`常用于数组去重,如`[...new Set(array)]`。了解它们的高级应用,如结构转换和高效查询,能提升代码质量。别忘了`WeakMap`用于弱引用键,防止内存泄漏。实践使用以加深理解。
|
5天前
|
存储 算法 NoSQL
C++一分钟之-map与set容器详解
【6月更文挑战第21天】C++ STL的`map`和`set`是基于红黑树的关联容器,提供有序存储和高效查找。`map`存储键值对,键唯一,值可重复;`set`仅存储唯一键。两者操作时间复杂度为O(log n)。常见问题包括键的唯一性和迭代器稳定性。自定义比较函数可用于定制排序规则,内存管理需注意适时释放。理解和善用这些工具能提升代码效率。
12 3
|
6天前
|
存储 编译器 C++
|
14天前
|
存储 安全 Java
Java集合详解:Set, Map, Vector, List的对比与联系
Java集合框架核心包括List、Set、Map和Vector。List允许重复元素,如ArrayList(适合读取)和LinkedList(适合插入删除)。Set不允许重复,有HashSet(无序)和TreeSet(排序)。Map存储键值对,HashMap(无序)和TreeMap(排序)。Vector是线程安全的ArrayList替代品,但在多线程环境下使用。选择集合类型应根据应用场景,如有序、无序、键值对需求及线程安全考虑。
|
17天前
|
存储 安全 Java
Java 集合(List、Set、Map 等)相关问答归纳再整理
HashMap 中使用键对象来计算 hashcode 值 HashSet 使用成员对象来计算 hashcode 值,对于两个对象来说hashcode 可能相同,所以 equals() 方法用来判断对象的相等性,如果两个对象不同的话,那么返回 false。 HashMap 比较快,因为是使用唯一的键来获取对象,HashSet 较 HashMap 来说比较慢。 4.1.3 HashMap 与 TreeMap
10 2
|
27天前
|
C语言
从C语言到C++_29(红黑树封装set和map)红黑树迭代器的实现(下)
从C语言到C++_29(红黑树封装set和map)红黑树迭代器的实现
27 3
|
28天前
|
存储 C语言 容器
从C语言到C++_26(set+map+multiset+multimap)力扣692+349+牛客_单词识别(下)
从C语言到C++_26(set+map+multiset+multimap)力扣692+349+牛客_单词识别
25 1
|
28天前
|
存储 C语言 容器
从C语言到C++_26(set+map+multiset+multimap)力扣692+349+牛客_单词识别(中)
从C语言到C++_26(set+map+multiset+multimap)力扣692+349+牛客_单词识别
27 1
|
26天前
|
存储 安全 Java
Java list set map等接口及其实现类
Java list set map等接口及其实现类
|
27天前
|
编译器 测试技术 C语言
从C语言到C++_29(红黑树封装set和map)红黑树迭代器的实现(上)
从C语言到C++_29(红黑树封装set和map)红黑树迭代器的实现
12 0