Vue props用法详解
![不指定 不指定](images/weather/blank.gif)
Vue props用法详解
组件接受的选项之一 props 是 Vue 中非常重要的一个选项。父子组件的关系可以总结为:
props down, events up
父组件通过 props 向下传递数据给子组件;子组件通过 events 给父组件发送消息。
父子级组件
比如我们需要创建两个组件 parent 和 child。需要保证每个组件可以在相对隔离的环境中书写,这样也能提高组件的可维护性。
这里我们先定义父子两个组件和一个 Vue 对象:
- <div id="example">
- <parent></parent>
- </div>
- var childNode = {
- template: `
- <div>childNode</div>
- `
- };
- var parentNode = {
- template: `
- <div>
- <child></child>
- <child></child>
- </div>
- `,
- components: {
- child: childNode
- }
- };
- new Vue({
- el: "#example",
- components: {
- parent: parentNode
- }
- });
这里的 childNode 定义的 template 是一个 div,并且内容是"childNode"字符串。
而在 parentNode 的 template 中定义了 div 的 class 名叫 parent 并且包含了两个 child 组件。
静态 props
组件实例的作用域是孤立的。这意味着不能(也不应该)在子组件的模板中直接饮用父组件的数据。要让子组件使用父组件的数据,需要通过子组件的 props 选项。
父组件向子组件传递数据分为两种方式:动态和静态,这里先介绍静态方式。
子组件要显示的用 props 声明它期望获得的数据
修改上例中的代码,给 childNode 添加一个 props 选项和需要的forChildMsg
数据;
然后在父组件中的占位符添加特性的方式来传递数据。
- var childNode = {
- template: `
- <div>
- {{forChildMsg}}
- </div>
- `,
- props: ["for-child-msg"]
- };
- var parentNode = {
- template: `
- <div>
- <p>parentNode</p>
- <child for-child-msg="aaa"></child>
- <child for-child-msg="bbb"></child>
- </div>
- `,
- components: {
- child: childNode
- }
- };
命名规范
对于 props 声明的属性,在父组件的 template 模板中,属性名需要使用中划线写法;
子组件 props 属性声明时,使用小驼峰或者中划线写法都可以;而子组件的模板使用从父组件传来的变量时,需要使用对应的小驼峰写法。别担心,Vue 能够正确识别出小驼峰和下划线命名法混用的变量,如这里的forChildMsg
和for-child-msg
是同一值。
动态 props
在模板中,要动态地绑定父组件的数据到子组件模板的 props,和绑定 Html 标签特性一样,使用v-bind
绑定;
基于上述静态 props 的代码,这次只需要改动父组件:
- var parentNode = {
- template: `
- <div>
- <p>parentNode</p>
- <child :for-child-msg="childMsg1"></child>
- <child :for-child-msg="childMsg2"></child>
- </div>
- `,
- components: {
- child: childNode
- },
- data: function() {
- return {
- childMsg1: "Dynamic props msg for child-1",
- childMsg2: "Dynamic props msg for child-2"
- };
- }
- };
在父组件的 data 的 return 数据中的 childMsg1 和 childMsg2 会被传入子组件中,
props 验证
验证传入的 props 参数的数据规格,如果不符合数据规格,Vue 会发出警告。
能判断的所有种类(也就是 type 值)有:
String, Number, Boolean, Function, Object, Array, Symbol
- Vue.component("example", {
- props: {
- // 基础类型检测, null意味着任何类型都行
- propA: Number,
- // 多种类型
- propB: [String, Number],
- // 必传且是String
- propC: {
- type: String,
- required: true
- },
- // 数字有默认值
- propD: {
- type: Number,
- default: 101
- },
- // 数组、默认值是一个工厂函数返回对象
- propE: {
- type: Object,
- default: function() {
- console.log("propE default invoked.");
- return { message: "I am from propE." };
- }
- },
- // 自定义验证函数
- propF: {
- isValid: function(value) {
- return value > 100;
- }
- }
- }
- });
- let childNode = {
- template: "<div>{{forChildMsg}}</div>",
- props: {
- "for-child-msg": Number
- }
- };
- let parentNode = {
- template: `
- <div class="parent">
- <child :for-child-msg="msg"></child>
- </div>
- `,
- components: {
- child: childNode
- },
- data() {
- return {
- // 当这里是字符串 "123456"时会报错
- msg: 123456
- };
- }
- };
还可以在 props 定义的数据中加入自定义验证函数,当函数返回 false 时,输出警告。
比如我们把上述例子中的 childNode 的for-child-msg
修改成一个对象,并包含一个名叫validator
的函数,该命名是规定叫validator
的,自定义函数名不会生效。
- let childNode = {
- template: "<div>{{forChildMsg}}</div>",
- props: {
- "for-child-msg": {
- validator: function(value) {
- return value > 100;
- }
- }
- }
- };
在这里我们给for-child-msg
变量设置了validator
函数,并且要求传入的值必须大于 100,否则报出警告。
单向数据流
props 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件五一修改父组件的状态。
所以不应该在子组件中修改 props 中的值,Vue 会报出警告。
- let childNode = {
- template: `
- <div class="child">
- <div>
- <span>子组件数据</span>
- <input v-model="forChildMsg"/>
- </div>
- <p>{{forChildMsg}}</p>
- </div>`,
- props: {
- "for-child-msg": String
- }
- };
- let parentNode = {
- template: `
- <div class="parent">
- <div>
- <span>父组件数据</span>
- <input v-model="msg"/>
- </div>
- <p>{{msg}}</p>
- <child :for-child-msg="msg"></child>
- </div>
- `,
- components: {
- child: childNode
- },
- data() {
- return {
- msg: "default string."
- };
- }
- };
这里我们给父组件和子组件都有一个输入框,并且显示出父组件数据和子组件的数据。当我们在父组件的输入框输入新数据时,同步的子组件数据也被修改了;这就是 props 的向子组件传递数据。而当我们修改子组件的输入框时,浏览器的控制台则报出错误警告
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "forChildMsg"
修改 props 数据
通常有两种原因:
- prop 作为初始值传入后,子组件想把它当做局部数据来用
- prop 作为初始值传入后,由子组件处理成其他数据输出
应对办法是
- 定义一个局部变量,并用 prop 的值初始化它
但是由于定义的 ownChildMsg 只能接受 forChildMsg 的初始值,当父组件要传递的值变化发生时,ownChildMsg 无法收到更新。
- let childNode = {
- template: `
- <div class="child">
- <div>
- <span>子组件数据</span>
- <input v-model="forChildMsg"/>
- </div>
- <p>{{forChildMsg}}</p>
- <p>ownChildMsg : {{ownChildMsg}}</p>
- </div>`,
- props: {
- "for-child-msg": String
- },
- data() {
- return { ownChildMsg: this.forChildMsg };
- }
- };
这里我们加了一个<p>用于查看 ownChildMsg 数据是否变化,结果发现只有默认值传递给了 ownChildMsg,父组件改变只会变化到 forChildMsg,不会修改 ownChildMsg。
- 定义一个计算属性,处理 prop 的值并返回
由于是计算属性,所以只能显示值,不能设置值。我们这里设置的是一旦从父组件修改了 forChildMsg 数据,我们就把 forChildMsg 加上一个字符串"---ownChildMsg",然后显示在屏幕上。这时是可以每当父组件修改了新数据,都会更新 ownChildMsg 数据的。
- let childNode = {
- template: `
- <div class="child">
- <div>
- <span>子组件数据</span>
- <input v-model="forChildMsg"/>
- </div>
- <p>{{forChildMsg}}</p>
- <p>ownChildMsg : {{ownChildMsg}}</p>
- </div>`,
- props: {
- "for-child-msg": String
- },
- computed: {
- ownChildMsg() {
- return this.forChildMsg + "---ownChildMsg";
- }
- }
- };
- 更加妥帖的方式是使用变量存储 prop 的初始值,并用 watch 来观察 prop 值得变化。发生变化时,更新变量的值。
- let childNode = {
- template: `
- <div class="child">
- <div>
- <span>子组件数据</span>
- <input v-model="forChildMsg"/>
- </div>
- <p>{{forChildMsg}}</p>
- <p>ownChildMsg : {{ownChildMsg}}</p>
- </div>`,
- props: {
- "for-child-msg": String
- },
- data() {
- return {
- ownChildMsg: this.forChildMsg
- };
- },
- watch: {
- forChildMsg() {
- this.ownChildMsg = this.forChildMsg;
- }
- }
- };
初入大前端小白们,需要明白的几个概念问题(持续更新)
![不指定 不指定](images/weather/blank.gif)
1, npm install是帮助安装 vue,或React到本地,npm install也可以安装vue,React的开发工具。当然你完全可以像jQuery一样自己找网站下载下来,在页面中引入。
2,没有npm可以使用vue,vue只是一个前端框架。
3,4,node是js的服务执行环境,前端常常借助 node帮助前端实现工程化。很多工具是基于node的,比如说你说的webpack,grunt。
5,webpack,grunt是前端工程化的工具,可以帮助前端完成混淆压缩,校验等工作。
6,7,实战中没用过,请参考官方文档http://cn.vuejs.org/v2/guide/...
8,可以单纯的利用 php+vue或者php+react开发。
9,最后一个问题太大,可以写本书。而且老实讲,一切都需要实战中才能有更深的体会。
最后总结一下:
前端圈所谓得“乱”,一个是近些年前端框架层出不穷,工程化,解决方案越来越多,已经脱离了一般人认为的那个“好单纯好不做作”的前端。就像后端开发有很多工具协作开发一样,前端也需要越来越多的工作完成前端面临巨大的工作量。 前端的行业发展已经不是那种后端在php,jsp中写一些html,前端来写一些css来完成工作的阶段。老实讲,我现在80%的时间在写js。前端已经不是后端开发的最后一步甚至“附属品”,而成为真正意义的“客户端”。复杂度也就慢慢和app等客户端越来越接近。
总的来说,你还是可以按照原先的开发方式来开发自己的应用,当然考虑引进工具一些先进的理念方法来协助开发。node,webpack,vue这些概念不应该成为自己开发中的阻碍,而是在自己在面临一些问题时的利剑。这些概念的学习需要一天一天的来,毕竟一口吃不成个胖子 :)
什么是npm?
从事网站制作的小前端们都知道cdn的概念,也就是在网站制作中如果我们需要jquery或者bootstrap等文件支持的话,就可以通过cdn引入的方式来实现调用。由于node的使用日益广泛,也带动了其组件npm的使用,而npm就是这些jquery以及bootstrap这些文件包的组合管理器。现在只要使用了node环境进行web网站开发,你就可以直接用npm进行调用以前所有的cdn文件了。
什么是webpack?
webpack简单来说就是前端代码资源的包管理工具,他自动整理你的项目结构,结合javascript的模块化组件,机型解析并交给浏览器渲染使用,大大提高前端的开发效率。
什么是vue-cli?它与vue脚手架有什么关系?
其实vue-cli就是vue的脚手架,vue脚手架的作用是用来自动一键生成vue+webpack的项目模版,包括依赖库,免去你手动安装各种插件,寻找各种cdn并一个个引入的麻烦。
什么是node.js?它与vue具体有什么关系?
提到vue就不得不说node了,vue作为一个前端框架技术,主要负责了数据渲染,界面展示效果,由于其易用性及便捷的维护应用日益广泛。而node作为一个服务器端语言,它是以javascript语言为基础的服务端程序语言,在实际的项目开发中,前端人员只要实现了环境的搭建,其实就可以仅仅从后台拿api接口进行数据调用,从而全部完成整个前端项目的展示。
前端由于近两年web前端技术发展革新速度飞快,一旦错过了,可能重新学的速度是非常慢的,只要尽早入手才能获得最好的学习效果。全栈网络专业从事郑州网站制作,我们也有专业的网站制作团队,愿意为每一个前端人员提供最新的前端知识分享。
vue await fetch 使用
![不指定 不指定](images/weather/blank.gif)
await/async 是 ES7 最重要特性之一,它是目前为止 JS 最佳的异步解决方案了。
- async function timeout() {
- return 'hello world';
- }
- async function timeout() {
- return 'hello world'
- }
- timeout();
- console.log('虽然在后面,但是我先执行');
fetch 基本使用方法点击 这里
下边一个小例子说个基本的请求吧
- <template>
- <div id="app">
- <button @click="fetchData()" >fetch 获取数据</button>
- <p>{{text}}</p>
- </div>
- </template>
- <script>
- export default {
- name: 'app',
- data () {
- return {
- text:''
- }
- },
- methods:{
- fetchData(){
- // fetch是相对较新的技术,当然就会存在浏览器兼容性的问题,当前各个浏览器低版本的情况下都是不被支持的,因此为了在所有主流浏览器中使用fetch 需要考虑 fetch 的 polyfill 了
- async function ff(){
- let data = await fetch('../static/data.json').then(res => res.json());
- console.log(data,'data');
- return data;
- }
- ff().then(res => {
- console.log(res,'res');
- this.text = 'name:'+res.name+',age:'+res.age+'sex:'+res.sex;
- }).catch(reason => console.log(reason.message));
- }
- }
- }
- </script>
- <style lang="scss">
- </style>
vue中 fetch跨域请求
![不指定 不指定](images/weather/blank.gif)
fetch 是原生javaScript提供的,它可以当作全局变量使用,挂载在window对象身上的
fetch的get请求方法
简单基本的fetch请求(get)
- <div id="app">
- <button @click="getData">get请求</button>
- </div>
- <script>
- 是原生javaScript提供的,它可以当作全局变量使用,挂载在window对象身上的
- new Vue({
- // fetch
- el:"#app",
- methods:{
- getData(){
- // var p=fetch();
- // console.log(p)//fetch方法也是promise对象
- fetch('./data/name.json')
- .then( (res) => { return res.json() } )//对fetch进行格式化,否则读取不到内容
- .then( (data) => { console.log(data)} )//拿到格式化后的数据data
- .catch(error=>console.log(error))
- },
- },
- })
注意事项:
A: fetch 的 get 请求的参数是直接连接在url上的, 我们可以使用Node.js提供的url或是qureystring模块来将
Object --> String
B: fetch 的请求返回的是Promise对象,所以我们可以使用.then().catch(),但是要记住.then()至少要写两个, 第一个then是用来格式
- 格式化处理的其他方式
- fetch('./data.json')
- .then(res=>{
- res.json() //格式化json数据
- //res.text()格式胡文本数据
- //res.blob()==格式化二进制文件==
- })
- .then( data => console.log(data))
- .catch( error => console.log( error ))
fetch的post请求方法
代码示例
- <div id="app">
- <button @click="postData">post请求</button>
- </div>
- <script>
- new Vue({
- // fetch
- el:"#app",
- methods:{
- postData(){
- fetch('http://10.31.161.60:8080',{
- method:'post',
- hearders:new Headers({
- //设置请求头,解决跨域问题
- 'Content-Type':'application/x-www-form-urlencoded'
- }),
- //解决请求数据类型限制的问题
- // body:new URLSearchParams([["a", 1],["b", 2]]).toString()
- })
- .then( res => res.text() )
- .then( data => console.log( data ))
- .catch( error => console.log( error ))
- }
- },
- })
总结
fetch要手动进行一次数据格式化,但是axios是内部进行了数据的格式化
fetch get 方法请求数据,参数要直接连接在url上
fetch 格式化数据 有三种 处理方法
.json() 格式化 json 类型数据, 将 json类型 string 转换成 json 对象
.text() 格式化文本
.blob() 格式化二进制数据
fetch 书写post请求、处理
设置请求头
通过 new URLSearchPrams 来携带参数
vue.js 跨域请求 fetch / axios
![不指定 不指定](images/weather/blank.gif)
假设我们的请求地址:http://localhost/Graduation_Thesis/a.php
在vue项目下 找到 config > index.js 文件;修改 index.js 文件下的 proxyTable 对象的内容;如下
- proxyTable: {
- '/api': { // '/api'相当于代表 http://localhost/Graduation_Thesis 可自行修改名字
- target: 'http://localhost/Graduation_Thesis', //我们需要请求的主要文件夹地址
- changeOrigin: true, //是否跨域
- pathRewrite: {
- '^/api': '' //路径重写
- }
- }
- },
这样就可以跨域请求 http://localhost/Graduation_Thesis 下的文件了,而需要获取文件下的 a.php 文件 需要用 fetch/ 来做请求
fetch 请求
fetch 类似于 ajax 数据提交,但 fetch 更好
- export default {
- name: 'App',
- components: {
- appHeader:Header
- },
- created(){
- fetch('/api/a.php',{ // /api既是上面跨域定义的文件地址
- method:"post", //请求方式
- headers: { //请求头
- 'Content-Type': 'application/json',
- 'Accept': 'application/json'
- },
- body:{ //发送的请求内容
- username:'hw',
- pass:'123'
- }
- }).then(res => {
- return res.json();
- }).then(res => {
- console.log(res);
- })
- }
- }
axios 请求
首先全局安装
- npm install axios
在 mian.js 引用
- //main.js
- import axios from 'axios'
- //让 axios 可以全局使用
- Vue.prototype.$axios = axios
这样就可以开始使用了
- export default {
- name: 'App',
- components: {
- appHeader:Header
- },
- created(){
- this.$axios.post("/api/a.php",{
- username:'hw',
- pass:'1123'
- })
- .then(res =>{
- console.log(res);
- })
- }
- }
vue中http请求
![不指定 不指定](images/weather/blank.gif)
前后端采用异步接口进行数据交互,传统情况下,我们采用jquery中的$.ajax()方法来进行异步请求。而在vue中我们并没有引入jquery而是采用了vue的插件vue-resource,它同样对异步请求进行了封装,方便我们同服务端进行数据交互。
1、引用及使用
- cnpm install vue-resource --save-dev
在项目根目录下/src/main.js中:
- import VueResource from 'vue-resource'
- Vue.use(VueResource)
此时在vue文件中就可以使用this.$http()进行网络请求。
2、通常在项目中是需要将http请求进行封装的。
为了封装成全局因此使用vuex。
参照 vue的一些总结 这个文章进行配置vuex
配置成功后,将main.js中的VueResource内容去掉,写在vuex中的store.js中
store.js内容如下
- import Vue from 'vue'
- import Vuex from 'vuex'
- import VueResource from 'vue-resource'
- Vue.use(Vuex)
- Vue.use(VueResource)
- export default new Vuex.Store({
- state: {
- url: 'www.baidu.com'
- },
- mutations: {
- setUrl (state, res) {
- // 该方法用来改变全局变量的值
- state.url = res
- }
- }
- })
3、在store.js中封装http请求的方法
- import Vue from 'vue'
- import Vuex from 'vuex'
- import VueResource from 'vue-resource'
- Vue.use(Vuex)
- Vue.use(VueResource)
- export default new Vuex.Store({
- state: {
- // url: 'www.baidu.com'
- },
- mutations: {
- // setUrl (state, res) {
- // // 该方法用来改变全局变量的值
- // state.url = res
- // },
- get(state, data) {
- Vue.http({
- method: 'GET',
- url: data.url,
- emulateJSON: true
- })
- .then(function (success) {
- // console.log("成功",success)
- data.success(success.body);
- }, function (error) {
- // console.log("错误",error)
- data.error(error.body);
- })
- /*
- Vue.http.get("http://test.dcsf.hebeiwanteng.com/api/common/wxParking/getNowTime")
- .then((success)=>{
- console.log("成功",success)
- })
- .catch((error)=>{
- console.log("失败",error)
- })
- */
- },
- post(state, data) {
- Vue.http({
- method: 'POST',
- url: data.url,
- params: data.data,
- emulateJSON: true
- }).then(function (success) {
- data.success(success.body);
- }, function (error) {
- data.error(error.body);
- })
- },
- delete(state, data) {
- Vue.http({
- method: 'DELETE',
- url: data.url,
- params: data.data,
- emulateJSON: true
- }).then(function (success) {
- data.success(success.body);
- }, function (error) {
- data.error(error.body);
- })
- },
- put(state, data) {
- Vue.http({
- method: 'PUT',
- url: data.url,
- params: data.data,
- emulateJSON: true
- }).then(function (success) {
- data.success(success.body);
- }, function (error) {
- data.error(error.body);
- })
- },
- }
- })
此时封装好了http请求。
在vue的文件中调用:
- <script>
- import { mapState, mapMutations } from 'vuex'
- export default {
- name: 'HelloWorld',
- data () {
- return {
- }
- },
- methods: {
- ...mapMutations(['get','post','delete','put']), //引入方法
- },
- created() {
- let _this = this;
- _this.get({
- url:"此处写请求地址",
- success(success) {
- console.log("成功",success)
- },
- error(error) {
- console.log("错误",error)
- }
- });
- }
- }
- </script>
4、注意:在store.js中使用Vue.http和在vue文件中使用this.$http是一样的。
5、该方法只验证了get请求,其它请求没有做验证。
JQ增加时间戳清除清除CSS缓存
![不指定 不指定](images/weather/blank.gif)
- /****** 拼接按天时间戳的方法 ******/
- var yearStr=new Date().getFullYear();
- var dateStr=new Date().getDate();
- var monthStr=(new Date().getMonth()+1+'');
- if(monthStr.length==1){
- monthStr = '0'+monthStr;
- }
- var timeStr=yearStr+'_'+monthStr+'_'+dateStr;
- //console.log(yearStr+'_'+monthStr+'_'+dateStr);
- /****** 遍历CSS按天增加时间戳 ******/
- $("link[type='text/css']").each(function(){
- console.log($(this).attr("href"))
- $(this).attr("href",$(this).attr("href")+"?t="+timeStr);
- });
vue常用开发ui框架(app,后台管理系统,移动端)及插件
![不指定 不指定](images/weather/blank.gif)
一、uni-app (app混合开发)
uni-app是一个使用Vue.js开发跨平台个人文库应用的前端框架,开发者编写一套代码,可编译到的iOS,安卓,H5,小程序等多个 平台。
官网:uni-app
二、vue-cli3+cordova (app混合开发)
网址:https://www.jianshu.com/p/543a1da430c2
三、element-ui (后台管理系统)
网址:http://element.eleme.io/#/zh-CN
四、vant-ui、mint-ui(移动端插件)
网站:mint-ui 好像很久没更新了,不过还是可以用
vant-ui 我自己用着还可以
五、weex(vue框架中最接近原生app开发)
在RN的大热下,基本上没人用,所以导致文档不全,社区不大。而且由于fluteer的降临,处境堪忧。但它是国产,我在心里支持它。
网址:http://weex.apache.org/cn/guide/
六、v-charts (基于 Vue2.0 和 ECharts 封装的图表组件)
个人感觉很好用
七、vue-awesome-swiper(vue轮播组件)
网址:https://www.npmjs.com/package/vue-awesome-swiper
八、 Lodash.js
一套工具库,内部封装了很多字符串、数组、对象等常见数据类型的处理函数,包括函数防抖和函数节流。
九、Moment.js (js日期处理类库)
十、vue-amap(地图组件)
只支持高德接口
网址:https://elemefe.github.io/vue-amap/#/
十一、nuxt.js( vue服务端渲染应用框架 )
co最简版实现,学习generator & co
![不指定 不指定](images/weather/blank.gif)
看了co的源码 比较难懂 了解了其原理后实现了一个最简版本https://github.com/yucong/simple-co 希望对想学习的tx有帮助~ yeild后面只支持thunk,co本身也是一个thunk 核心代码:
- function co(generator) {
- return function(fn) {
- var gen = generator();
- function next(err, result) {
- if(err){
- return fn(err);
- }
- var step = gen.next(result);
- if (!step.done) {
- step.value(next);
- } else {
- fn(null, step.value);
- }
- }
- next();
- }
- }
用法:
- var co = require('./co');
- // wrap the function to thunk
- function readFile(filename) {
- return function(callback) {
- require('fs').readFile(filename, 'utf8', callback);
- };
- }
- co(function * () {
- var file1 = yield readFile('./file/a.txt');
- var file2 = yield readFile('./file/b.txt');
- console.log(file1);
- console.log(file2);
- return 'done';
- })(function(err, result) {
- console.log(result)
- });
会打印出: content in a.txt content in b.txt done
下面做个简单对比:
传统方式,sayhello
是一个异步函数,执行helloworld
会先输出"world"
再输出"hello"
。
- function sayhello() {
- return Promise.resolve('hello').then(function(hello) {
- console.log(hello);
- });
- }
- function helloworld() {
- sayhello();
- console.log('world');
- }
- helloworld();
输出
- > "world"
- > "hello"
co 的方式,会先输出"hello"
再输出"world"
。
- function co(gen) {
- var it = gen();
- var ret = it.next();
- ret.value.then(function(res) {
- it.next(res);
- });
- }
- function sayhello() {
- return Promise.resolve('hello').then(function(hello) {
- console.log(hello);
- });
- }
- co(function *helloworld() {
- yield sayhello();
- console.log('world');
- });
输出
- > "hello"
- > "world"
消除回调金字塔
假设sayhello
/sayworld
/saybye
是三个异步函数,用真正的 co 模块就可以这么写:
- var co = require('co');
- co(function *() {
- yield sayhello();
- yield sayworld();
- yield saybye();
- });
输出
- > "hello"
- > "world"
- > "bye"