03、Promise,Vue-cli搭建项目

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](http://upload-images.jianshu.io/upload_images/3680331-2d24a6e125a00eb8.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)



按回车![image](http://upload-images.jianshu.io/upload_images/3680331-f845ed9be840e3d3.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)



按回车![image](http://upload-images.jianshu.io/upload_images/3680331-2acdffa3b4572408.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)



按回车![image](http://upload-images.jianshu.io/upload_images/3680331-f4d15d222beab92e.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)



使用默认选项 Runtime + Compile 即可,直接按回车![image](http://upload-images.jianshu.io/upload_images/3680331-9c03ebac148c260f.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


输入 Y,按回车![image](http://upload-images.jianshu.io/upload_images/3680331-808dcaf0fc96a4a8.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)



输入 n,按回车![image](http://upload-images.jianshu.io/upload_images/3680331-09d68e206aa3280b.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)



输入 n,按回车![image](http://upload-images.jianshu.io/upload_images/3680331-7ad18f8d05fa766b.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)



输入 n,按回车![image](http://upload-images.jianshu.io/upload_images/3680331-3eb0aa018d1fe6e3.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


使用默认的 npm 作为包管理工具,直接按回车

等待安装,安装完毕后

进入当前项目目录

cd vue-evernote-client


安装依赖

npm install


![image](http://upload-images.jianshu.io/upload_images/3680331-b196241e84e1386a.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

启动server

npm run dev


浏览器打开 [http://localhost:8080](http://localhost:8080/ "null") ,即可看到搭建好的初始界面

![image](http://upload-images.jianshu.io/upload_images/3680331-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 // 项目基本信息

猜你喜欢

转载自blog.csdn.net/weixin_34320159/article/details/87150551