一:Vue前言

Vue是单页面Web应用(SPA)

单页面Web应用(Single Page Web Application)简称SPA ,就是只有一个Web页面的应用,是加载单个HTML页面并在用户与应用程序交互时动态更新Web页面的Web应用程序,单页面应用程序时加载单个Html页面并在用户与应用程序交互式动态更行该页面的Web应用程序,浏览器一开始回家再必须的HtmlCSS JS,所有的操作都在这个页面上完成,都由JS来控制。

前后端分离的开发模式

前言:前后端分离的开发模式 不论是单页面Web应用还是多页面应用程序 都可以采用;

前后端分离开发模式的基本流程如下

<1> 项目立项

<2>需求分析

<3>服务端的工作

1需求分析

2数据库设计

3接口设计

4接口开发

<4>前端的工作

1需求分析

2写界面和功能

3通过接口和服务端交互

如果你熟悉MVC的开发模式 你应该可以想到MVC中的V 便是前端负责的主要工作;

MVVM

MVVM是前端视图层的分成开发思想 主要把页面分成了M V VM 其中VM是MVVM的思想核心 因为VM是M和V之间的调度者 ,他负责数据的双向绑定 MVVM思想主要是为了让我们开发更方便

Primise的结束

Promise 是异步编程的一种解决方案:从语法上讲,promise是一个对象,从它可以获取异步操作的消息;从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。promise有三种状态: pending(等待态),fulfiled(成功态),rejected(失败态);状态一旦改变,就不会再变。创造promise实例后,它会立即执行。

 

 

 

 

 

 

Promise 是一个构造函数,它自身拥有all、reject、resolve这几个眼熟的方法,
原型上有then、catch等同样熟悉的方法。
所以,在开始一个Promise的时候,先new一个吧:

let p = new Promise((resolve, reject)=> {
setTimeout(()=> {
resolve('执行完成')
}, 1000)
})

 



Promise是一个构造函数,接受一个回调函数作为参数,回调函数的参数是resolve、reject。分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数。其实这里用“成功”和“失败”来描述并不准确,按照标准来讲,resolve是将Promise的状态置为fullfiled,reject是将Promise的状态置为rejected。不过在我们开始阶段可以先这么理解,后面再细究概念。

在上面的代码中,我们执行了一个异步操作,也就是setTimeout,1秒后,输出“执行完成”,并且调用resolve方法。

注意!我只是new了一个对象,并没有调用它,我们传进去的函数就已经执行了,这是需要注意的一个细节。所以我们用Promise的时候一般是包在一个函数中,在需要的时候去运行这个函数,如:

function runAsync() {
let p = new Promise((resolve, reject)=> {
setTimeout(()=> {
console.log('执行完成');
resolve(123);
}, 1000)
})
return p;
}

runAsync()

 


这时候你应该有个疑问:包装这么一个函数有什么作用?
在我们包装好的函数最后,会return出Promise对象 p,也就是说,执行这个函数我们得到了一个Promise对象。Promise对象上有then、catch方法,这这个时候就可以用到它们了,看下面的代码:

runAsync().then((result)=> {
console.log(result);
// 做其他操作
})

 


在runAsync()的返回上直接调用then方法,then接收一个参数,是函数,并且会拿到我们在runAsync中调用resolve时传的的参数。运行这段代码,会在1秒后输出“执行完成”,紧接着输出 “123” 。

这个时候你可能已经明白了,原来then方法和我们平时写的回调函数是一个道理,那我们直接写回调函数就行了啊,为什么还要写Promise呢?

确实在一些简单的场景下,回调函数已经够用,但是在现在前端的大环境和大发展的状态下,经常会出现回调地狱的情况,你可能需要在回调函数中,再继续回调函数,这样下去就会很恐怖了。Promise就给我们带来了更好的解决办法。
Promise的优势在于,可以在then方法中继续写Promise对象并返回,然后继续调用then来进行回调操作。
链式操作的用法
看下面一个例子,多层回调时是怎么使用的:

function runAsync1() {
var p = new Promise(function(resolve, reject) {
setTimeout(function(){
console.log('执行完成1');
resolve(1);
}, 1000)
})
return p;
}

function runAsync2() {
var p = new Promise(function(resolve, reject) {
setTimeout(function(){
console.log('执行完成2');
resolve(2);
}, 1000)
})
return p;
}


function runAsync3() {
var p = new Promise(function(resolve, reject) {
setTimeout(function(){
console.log('执行完成3');
resolve(3);
}, 1000)
})
return p;
}

runAsync1().then(function(data) {
console.log(data);
return runAsync2();
}).then(function(data) {
console.log(data);
return runAsync3();
}).then(function(data) {
console.log(data);
return '直接返回数据'
}).then(function(data) {
console.log(data);
})

 

在链式操作中,当一个Promise结束后,可以继续返回一个新的Promise,在下一个then方法中继续接收其返回的resolve。

在then方法中,你也可以直接return数据而不是Promise对象,在后面的then中就可以接收到数据了,看上面例子的最后一个。

reject的用法
说完resolve ,就不得不说reject,它们都是Promise自身的方法,简单来说,reject方法返回的是错误信息,将Promise的状态置为rejected,上面已经说过。

我们下面来看看具体的实现:

function getNumber() {
var p = new Promise(function(resolve, reject) {
setTimeout(function(){
var num = Math.ceil(Math.random()*10);
if(num<5) {
resolve(num)
} else {
reject('数字太大了')
}
}, 1000)
});
return p;
}
getNumber()
.then(
function(data) {
console.log('resolve')
console.log(data);
},
function(reason) {
console.log('reject')
console.log(reason);
}
)

 



我们创建一个随机1-10的数,判断大小,返回不同的resolve和reject。

首先我们可以在then方法中第二个参数来接收reject返回值。如果是大于5我们就会打印出数字太大了。

但是很多人之前都有接触过Promise,知道还有一个catch的链式操作方法。它也可以用来接收reject返回的信息。来看下面的代码:

getNumber()
.then(function(data) {
console.log('resolve');
console.log(data);
})
.catch(function(reason) {
console.log('reject');
console.log(reason);
})

 



如果数字大于5就会打印 reject 6。

如果你在then中出现了错误,也不会中断程序的运行,会在catch中打印出错误信息:

 1 getNumber()
 2 .then(function(data) {
 3 console.log('resolve');
 4 console.log(data);
 5 console.log(somedata);
 6 })
 7 .catch(function(reason) {
 8 console.log('reject');
 9 console.log(reason); // ReferenceError: somedata is not defined
10 })
11 
12 Promise.all()
13 简单来说,all的作用就是并行执行多个异步操作,然后在最后一个异步程序结束后,再继续下面的方法。
14 
15 Promise // 用Promise.all来执行,all接收一个数组参数,里面的值最终都算返回Promise对象。
16 .all([runAsync1(), runAsync2(), runAsync3()])
17 .then(function(data) {
18 console.log(data); // [1, 2, 3]
19 });

 

runAsync1(), runAsync2(), runAsync3()是我们上面中写过的方法,不清楚的可以往上面翻一翻

根据上面的代码我们可以看到,当三个异步程序都执行完成后,在then方法中一次返回一个data数组,是三个异步程序的返回值组成的集合。

方法很简单,那这个方法在现实中,有哪些实用的地方呢?

打开网页时,预先加载需要用到的各种资源如图片、flash以及各种静态文件。
所有的都加载完后,我们再进行页面的初始化

下面我们来看一个跟all相似,但是运行过程不同的方法race。

Promise.race()
all方法的效果实际上是「谁跑的慢,以谁为准执行回调」,
那么相对的就有另一个方法「谁跑的快,以谁为准执行回调」,这就是race方法

 

race 的用法:

Promise
.race([runAsync1(), runAsync2(), runAsync3()])
.then(function(data){
console.log(data); // 
})

因为第一个方法先结束,所以程序就到在此运行到then方法, 返回的 1

现实中 race 的使用也很多

可以用race给某个异步请求设置超时时间,并且在超时后执行相应的操作

/*---------- race 使用场景 ----------------*/

// 请求某个图片资源

function requestImg() {
var p = new Promise(function(resolve, reject) {
var img = new Image();
img.src = 'http://www.google.cn/landing/cnexp/google-search.png';
img.onload = function() {
resolve(img)
}
});
return p;
}

// 延时函数,用于给请求记时
function timeout() {
var p = new Promise(function(resolve, reject) {
setTimeout(function() {
reject('请求超时')
}, 5000)
});
return p;
}

Promise
.race([requestImg(), timeout()])
.then(function(data) {
console.log(data);
document.body.appendChild(data);
})
.catch(function(reason) {
console.log(reason);
})

 


如果你把图片的url地址替换成一个不存在的地址,那么系统会报404的错误,在接下来的catch中,会打印出错误信息请求超时

posted @ 2021-09-01 09:43  三五八团楚云飞  阅读(85)  评论(0)    收藏  举报