美文网首页
03、Promise,Vue-cli搭建项目

03、Promise,Vue-cli搭建项目

作者: 时修七年 | 来源:发表于2019-01-27 19:34 被阅读29次

    Promise 对象

    看看一个例子

    function fn1() {
      setTimeout(()=>{
        console.log('fn1')
      }, 1000)
    }
    
    function fn2() {
      setTimeout(()=>{
        console.log('fn2')
      }, 1000)
    }
    
    function fn3() {
      setTimeout(()=>{
        console.log('fn3')
      }, 1000)
    }
    
    

    对于以上代码如何实现: 1秒钟之后输出 fn1, 再过疫苗输出 fn2, 再过1秒输出 fn3 ?

    可如下改装:

    function fn1(callback) {
      setTimeout(()=>{
        console.log('fn1')
        callback()
      }, 1000)
    }
    
    function fn2(callback) {
      setTimeout(()=>{
        console.log('fn2')
        callback()
      }, 1000)
    }
    
    function fn3() {
      setTimeout(()=>{
        console.log('fn3')
      }, 1000)
    }
    
    fn1(function(){
      fn2(function(){
        fn3()
      })
    })
    
    

    回调地狱!

    什么是 Promise

    参考阮一峰 ES6教程

    Promise 是一个对象,对象里存储一个状态,这个状态是可以随着内部的执行转化的,为以下三种状态之一:等待态(Pending)、完成态(Fulfilled)、拒绝态(Rejected)。

    一开始,我们先设置好等状态从 pending 变成 fulfilled 和 rejected 的预案(当成功后我们做什么,失败时我们做什么)。

    Promise 启动之后,当满足成功的条件时我们让状态从 pending 变成 fullfilled (执行 resolve);当满足失败的条件,我们让状态从 pending 变成 rejected(执行 reject)

    Promise 范例

    范例1

    Promise.prototype.then / Promise.prototype.catch

    function getIp() {
      var promise = new Promise(function(resolve, reject){
        var xhr = new XMLHttpRequest()
        xhr.open('GET', 'https://easy-mock.com/mock/5ac2f80c3d211137b3f2843a/promise/getIp', true)
        xhr.onload = function(){
          var retJson = JSON.parse(xhr.responseText)  // {"ip":"58.100.211.137"}
          resolve(retJson.ip)
        }
        xhr.onerror = function(){
          reject('获取IP失败')
        }
        xhr.send()
      })
      return promise
    }
    
    function getCityFromIp(ip) {
      var promise = new Promise(function(resolve, reject){
        var xhr = new XMLHttpRequest()
        xhr.open('GET', 'https://easy-mock.com/mock/5ac2f80c3d211137b3f2843a/promise/getCityFromIp?ip='+ip, true)
        xhr.onload = function(){
          var retJson = JSON.parse(xhr.responseText)  // {"city": "hangzhou","ip": "23.45.12.34"}
          resolve(retJson.city)
        }
        xhr.onerror = function(){
          reject('获取city失败')
        }
        xhr.send()
      })
      return promise
    }
    function getWeatherFromCity(city) {
      var promise = new Promise(function(resolve, reject){
        var xhr = new XMLHttpRequest()
        xhr.open('GET', 'https://easy-mock.com/mock/5ac2f80c3d211137b3f2843a/promise/getWeatherFromCity?city='+city, true)
        xhr.onload = function(){
          var retJson = JSON.parse(xhr.responseText)   //{"weather": "晴天","city": "beijing"}
          resolve(retJson)
        }
        xhr.onerror = function(){
          reject('获取天气失败')
        }
        xhr.send()
      })
      return promise
    }
    
    getIp().then(function(ip){
      return getCityFromIp(ip)
    }).then(function(city){
      return getWeatherFromCity(city)
    }).then(function(data){
      console.log(data)
    }).catch(function(e){
      console.log('出现了错误', e)
    })
    
    

    Promise.all

    范例2

    
    function getCityFromIp(ip) {
      var promise = new Promise(function(resolve, reject){
        var xhr = new XMLHttpRequest()
        xhr.open('GET', 'https://easy-mock.com/mock/5ac2f80c3d211137b3f2843a/promise/getCityFromIp?ip='+ip, true)
        xhr.onload = function(){
          var retJson = JSON.parse(xhr.responseText)  // {"city": "hangzhou","ip": "23.45.12.34"}
          resolve(retJson)
        }
        xhr.onerror = function(){
          reject('获取city失败')
        }
        xhr.send()
      })
      return promise
    }
    
    var p1 = getCityFromIp('10.10.10.1')
    var p2 = getCityFromIp('10.10.10.2')
    var p3 = getCityFromIp('10.10.10.3')
    
    //Promise.all, 当所有的 Promise 对象都完成后再执行
    详情,评价,购买人群
    Promise.all([p1, p2, p3]).then(data=>{
      console.log(data)
    })
    
    

    Pomise.all的使用

    Promise.all可以将多个Promise实例包装成一个新的Promise实例。同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值。

    let p1 = new Promise((resolve, reject) => {
      resolve('成功了')
    })
    
    let p2 = new Promise((resolve, reject) => {
      resolve('success')
    })
    
    let p3 = Promse.reject('失败')
    
    Promise.all([p1, p2]).then((result) => {
      console.log(result)               //['成功了', 'success']
    }).catch((error) => {
      console.log(error)
    })
    
    Promise.all([p1,p3,p2]).then((result) => {
      console.log(result)
    }).catch((error) => {
      console.log(error)      // 失败了,打出 '失败'
    })
    

    Promse.all在处理多个异步处理时非常有用,比如说一个页面上需要等两个或多个ajax的数据回来以后才正常显示,在此之前只显示loading图标。

    let wake = (time) => {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(`${time / 1000}秒后醒来`)
        }, time)
      })
    }
    
    let p1 = wake(3000)
    let p2 = wake(2000)
    
    Promise.all([p1, p2]).then((result) => {
      console.log(result)       // [ '3秒后醒来', '2秒后醒来' ]
    }).catch((error) => {
      console.log(error)
    })
    

    需要特别注意的是,Promise.all获得的成功结果的数组里面的数据顺序和Promise.all接收到的数组顺序是一致的,即p1的结果在前,即便p1的结果获取的比p2要晚。这带来了一个绝大的好处:在前端开发请求数据的过程中,偶尔会遇到发送多个请求并根据请求顺序获取和使用数据的场景,使用Promise.all毫无疑问可以解决这个问题。
    二、Promise.race的使用
    顾名思义,Promse.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。

    let p1 = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('success')
      },1000)
    })
    
    let p2 = new Promise((resolve, reject) => {
      setTimeout(() => {
        reject('failed')
      }, 500)
    })
    
    Promise.race([p1, p2]).then((result) => {
      console.log(result)
    }).catch((error) => {
      console.log(error)  // 打开的是 'failed'
    })
    
    

    //Promise.all, 当所有的 Promise 对象都完成后再执行
    Promise.race([p1, p2, p3]).then(data=>{
    console.log(data)
    })

    
    对于开头回调地狱的解决
    
    

    function fn1() {
    return new Promise((resolve, reject)=>{
    setTimeout(()=>{
    console.log('fn1...')
    resolve()
    }, 1000)
    })
    }

    function fn2() {
    return new Promise((resolve, reject)=>{
    setTimeout(()=>{
    console.log('fn2...')
    resolve()
    }, 1000)
    })
    }

    function fn3() {
    return new Promise((resolve, reject)=>{
    setTimeout(()=>{
    console.log('fn3...')
    resolve()
    }, 1000)
    })
    }

    function onerror() {
    console.log('error')
    }

    fn1().then(fn2).then(fn3).catch(onerror)

    
    ---
    # 使用脚手架搭建项目
    
    ## 安装
    
    打开终端,切换到一个经常使用的项目目录,如
    
    

    cd ~/projects

    
    全局安装 vue-cli
    
    

    npm install -g vue-cli

    
    使用 vue-cli 创建 基于webpack模板的新项目
    
    

    vue init webpack vue-evernote-client

    
    ![image](https://img.haomeiwen.com/i3680331/2d24a6e125a00eb8.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    
    
    按回车![image](https://img.haomeiwen.com/i3680331/f845ed9be840e3d3.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    
    
    按回车![image](https://img.haomeiwen.com/i3680331/2acdffa3b4572408.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    
    
    按回车![image](https://img.haomeiwen.com/i3680331/f4d15d222beab92e.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    
    
    使用默认选项 Runtime + Compile 即可,直接按回车![image](https://img.haomeiwen.com/i3680331/9c03ebac148c260f.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    
    输入 Y,按回车![image](https://img.haomeiwen.com/i3680331/808dcaf0fc96a4a8.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    
    
    输入 n,按回车![image](https://img.haomeiwen.com/i3680331/09d68e206aa3280b.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    
    
    输入 n,按回车![image](https://img.haomeiwen.com/i3680331/7ad18f8d05fa766b.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    
    
    输入 n,按回车![image](https://img.haomeiwen.com/i3680331/3eb0aa018d1fe6e3.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    
    使用默认的 npm 作为包管理工具,直接按回车
    
    等待安装,安装完毕后
    
    进入当前项目目录
    
    

    cd vue-evernote-client

    
    安装依赖
    
    

    npm install

    
    ![image](https://img.haomeiwen.com/i3680331/b196241e84e1386a.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    启动server
    
    

    npm run dev

    
    浏览器打开 [http://localhost:8080](http://localhost:8080/ "null") ,即可看到搭建好的初始界面
    
    ![image](https://img.haomeiwen.com/i3680331/9adbc38fedef364a.jpg-middle?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    可以使用编辑器打开 vue-evernote-client 这个目录,阅读代码,目前我们暂时只需要关注 src 这个目录即可。
    
    

    |-- build // 项目构建(webpack)相关代码
    | |-- build.js // 生产环境构建代码
    | |-- check-version.js // 检查node、npm等版本
    | |-- dev-client.js // 热重载相关
    | |-- dev-server.js // 构建本地服务器
    | |-- utils.js // 构建工具相关
    | |-- webpack.base.conf.js // webpack基础配置
    | |-- webpack.dev.conf.js // webpack开发环境配置
    | |-- webpack.prod.conf.js // webpack生产环境配置
    |-- config // 项目开发环境配置
    | |-- dev.env.js // 开发环境变量
    | |-- index.js // 项目一些配置变量
    | |-- prod.env.js // 生产环境变量
    | |-- test.env.js // 测试环境变量
    |-- src // 源码目录
    | |-- components // vue公共组件
    | |-- apis // 请求接口
    | |--utils // 工具库
    | |-- views // 业务组件
    | |-- store // vuex的状态管理
    | |-- App.vue // 页面入口文件
    | |-- main.js // 程序入口文件,加载各种公共组件
    |-- static // 静态文件,比如一些图片,json数据等
    | |-- data // 群聊分析得到的数据用于数据可视化
    |-- .babelrc // ES6语法编译配置
    |-- .editorconfig // 定义代码格式
    |-- .gitignore // git上传需要忽略的文件格式
    |-- README.md // 项目说明
    |-- favicon.ico
    |-- index.html // 入口页面
    |-- package.json // 项目基本信息

    ![code.png](https://img.haomeiwen.com/i3680331/d7fdfaa3f3497ce8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    

    相关文章

      网友评论

          本文标题:03、Promise,Vue-cli搭建项目

          本文链接:https://www.haomeiwen.com/subject/sejnjqtx.html