2019-04-03 | CRM | UNLOCK

400 客服电话 和 Promise

参考书籍: 深入理解 ES6 和你不知道的 JS(中卷)
初衷: 自己对回调和Promise 的理解一直都是很片面的,所以一直都想系统性的梳理一下异步的一些知识

Promise 简介

Promise 是抽象异步处理对象以及对其进行各种操作的组件,一旦 Promise 决议,它就永远保持在这个状态。此时它就成为了不变值(immutable value),可以根据需求多次查看。

目前大致有下面三种类型

  • Constructor: 创建一个 promise 对象、可以使用 new 来调用 Promise 的构造器来进行实例化
  • Method:
    • resolve
    • reject
    • promise.then()
    • promise.catch()
  • Static Method
    • Promise.all([…])
    • Promise.race([…])
    • Promise.resolve()
    • Promise.reject()

三种状态
promise 对象的状态,从 Pending 转换为 FulfilledRejected 之后, 这个 promise 对象的状态就不会再发生任何变化

  • Fulfilled
  • Rejected
  • Pending

Promise.resolve()

Promise.resolve() 有三种类型, 本身就是一个语法糖

  • Promise.resolve(value);

    静态方法 Promise.resolve(value) 可以认为是 new Promise() 方法的快捷方式

  • Promise.resolve(promise);
  • Promise.resolve(theanable);

    thenable 对象转换为 promise 对象

var foo = {
    then: (resolve, reject) => resolve('foo')
};
var resolved = Promise.resolve(foo);
// 相当于
var resolved = new Promise((resolve, reject) => {
    foo.then(resolve, reject)
});

resolved.then((str) =>
    console.log(str);//foo
)

promise 使用的注意事项

  • 接受两个参数(resolve, reject),在最后必须要其中的一个,在返回 reject() 时,需要配合 return reject(...) 来打断运行和返回错误信息,如果不返回任何结果,这个 promise 将被挂起,一直处于 loading 状态
  • 在外部 catch() 捕捉
  • 应用 promise 对象时不能够直接赋值给一个参数,可以通过以下两种简答的方法
    • async await 一直到最后 resolve 或者 reject 返回的不再是一个 promise 对象是才会真正的结束 (推荐使用)
    • then 使用 then接受 promise 返回的值

缺陷

  • 错误处理
  • 无法取消

使用 Promise 封转呼叫中心暴露出来的公用方法

主要方法的封装

import init from './acc/init'
import { Message } from 'element-ui'
import authority from './authority'
const telephone = {
  init() {
    return init()
  },
  onLine: async () => {
    // 在线
    const workbench = await init()
    return new Promise(resolve => {
      workbench.online()
      resolve(workbench)
    })
  },
  onLeave: async () => {
    // 离开
    const workbench = await init()
    return new Promise(resolve => {
      setTimeout(() => {
        workbench.applyForBreak()
        resolve(workbench)
      }, 1000)
    })
  },
  removePhone: async (mobileNumber, caller) => {
    // mobileNumber 转接手机 caller客服电话
    const workbench = await init()
    return new Promise(resolve => {
      workbench.offline(mobileNumber, caller)
      resolve(workbench)
    })
  },
  out: async () => {
    const workbench = await init()
    return new Promise(resolve => {
      workbench.onLogOut()
      window.workbench = ''
      resolve()
    })
  },
  ready: async () => {
    // 上线和结束处理后调用
    const workbench = await init()
    return new Promise(resolve => {
      workbench.ready()
      window.workbench = ''
      resolve()
    })
  },
  call: async (phoneNum, boolean) => {
    const workbench = await init()
    return new Promise(resolve => {
      // boolean: true 虚拟外呼
      workbench.call(phoneNum, '', '', boolean)
      resolve(workbench)
    })
  },
  answerPhone: async () => {
    const workbench = await init()
    return new Promise(resolve => {
      workbench.answer()
      resolve(workbench)
    })
  },
  hangUp: async () => {
    const workbench = await init()
    return new Promise(resolve => {
      workbench.hangUp()
      resolve(workbench)
    })
  },
  thirdCallTransfer: async callee => {
    // 转接客服 callee坐席的分机号,转接坐席
    const workbench = await init()
    return new Promise(resolve => {
      workbench.thirdCallTransfer(callee, '')
      resolve(workbench)
    })
  },
  checkStatus: async () => {
    const workbench = await init()
    return new Promise((resolve, reject) => {
      const { code } = workbench.getStatusCode()
      const { callStatus } = authority.get() || {}
      if (callStatus === 'removePhone') {
        Message.warning('当前处于转接手机状态,请切换至在线状态')
        return reject()
      }
      if (code === 4) {
        Message.warning('当前处于离开状态,请切换至在线状态')
        return reject()
      }
      resolve()
    })
  }
}

export default telephone