vue中promise的使用

  promise是处理异步的利器,在之前的文章《ES6之promise》中,我详细介绍了promise的使用, 在文章《js动画实现&&回调地狱&&promise》中也提到了promise的then的链式调用, 这篇文章主要是介绍在实际项目中关于异步我遇到的一些问题以及解决方法,由此来加深对promise的进一步理解。

背景

  进入商品页,商品页的左侧是分类,右侧是具体的商品,一旦进入商品页,就把所有分类的商品请求出来,注意: 必须要按照顺序。

  

实现思路

在商品页, created 钩子函数触发获取分类的http请求,请求到结果后,开始请求所有的具体商品并渲染。

遇到的问题

  • 由于请求商品分类是异步的, 怎么判断异步请求完成, 也就是说请求具体商品的时机是什么时候。
  • 获取到所有的商品必须发送请求,请求时异步的,怎么保证能够按照顺序获取到。

解决问题 --- 问题一

  针对问题一,最好的方式还是使用promise,大致实现如下:

    getClassify: function () {
var that = this;
// 使用promise处理异步。
this.updateKinds().then(function () {
console.log("获取分类结束!");
that.updateAllContent();
});
},

  其中getClassify是在created时就会调用的,而updateKinds是actions中的方法,我们先看看actions中是怎么写的:

updateKinds ({commit, state}) {
return new Promise(function (resolve, reject) {
axios.get('/bbg/shop/get_classify', {
params: {
sid:
}
})
.then(function (response) {
if (response.data.code == ) {
commit(UPDATE_KINDS, response.data.data)
console.log(response.data.data);
resolve()
}
}).catch(function (error) {
console.log(error);
});
});

  即返回一个promise,当请求到数据,并且commit之后,我们就额可以resolve()了,这样,就可以在then中执行获取所有内容的方法了。

  虽然实现起来比较简单,但是这个思想更好。

解决问题 --- 问题二

  在问题一中,我们看到resolve之后就可以调用updateAllContent() 了,那么这个应该怎么写呢?

  首先可以确定的是: 因为需要请求的分类不只一个,所以要使用promise, 并且一定要返回一个promise,这样才能继续链式调用,其中一部分如下:

ar items = state.items;
function getItemPromise(id) {
return new Promise(function (resolve, reject) {
var content = {
"isSingle": ,
"sbid": ,
"catalog3": id,
"offset": ,
"pageSize":
};
axios.post('/bbg/goods/get_goods_list_wechat', qs.stringify({"data": JSON.stringify(content)}))
.then(function (response) {
if (response.data.code == ) {
for (let i = ; i < response.data.data.length; i++) {
commit(UPDATE_ALL_CONTENT, response.data.data[i]);
}
resolve();
}
}).catch(function (error) {
console.log(error);
});
});
}

  即调用这个函数,传入一个分类的id,然后就可以发送请求了,获取到数据之后,就把数据插入到 内容的数组中, 最后resolve()还告诉then可以执行了。

  注意: 如何更新一个数组呢? 

    [UPDATE_ALL_CONTENT] (state, item) {
state.contentItems = [...state.contentItems, Object.assign({}, item)];
},

  这样就相当于push了。

 上面的这个函数的意义在于封装请求,那么对于请求多个时,如何做到呢?

  我之前尝试了下面两种方法:

FIRST

    // first method
var promise = getItemPromise(items[].id)
for (let j = ; j < items.length; j++) {
promise.then(function () {
return getItemPromise(items[j].id);
})
}

 思路就是先请求第一个分类,然后循环,实际上和下面的效果是一样的:

var promise = getItemPromise(items[].id);
promise.then(function () {
console.log("", window.performance.now());
return getItemPromise(items[].id);
});
promise.then(function () {
console.log("", window.performance.now());
return getItemPromise(items[].id);
});
promise.then(function () {
console.log("", window.performance.now());
return getItemPromise(items[].id);
});
promise.then(function () {
console.log("", window.performance.now());
return getItemPromise(items[].id);
});
promise.then(function () {
console.log("", window.performance.now());
return getItemPromise(items[].id);
});
promise.then(function () {
console.log("", window.performance.now());
return getItemPromise(items[].id);
});

问题: 通过这样的方法最终请求的数据是可以请求到的,但是顺序并没有按照我们预想的思路来执行,因为这样的执行方式会在getItemPromise执行之后就立即同时执行后面几个then,所以最终得到的顺序是不能确定的。 

方法二:

      // second method
var somePromise = getItemPromise(items[].id);
for (let k = ; k < items.length; k++) {
somePromise = somePromise.then(function () {
return getItemPromise(items[k].id);
});
}

 这种方法的结构类似于下面这样:

getItemPromise(items[].id)
.then(function () {
console.log("", window.performance.now());
return getItemPromise(items[].id);
})
.then(function () {
console.log("", window.performance.now()); return getItemPromise(items[].id);
})
.then(function () {
console.log("", window.performance.now()); return getItemPromise(items[].id);
})
.then(function () {
console.log("", window.performance.now()); return getItemPromise(items[].id);
})
.then(function () {
console.log("", window.performance.now()); return getItemPromise(items[].id);
})
.then(function () {
console.log("", window.performance.now()); return getItemPromise(items[].id);
})
.then(function () {
console.log("", window.performance.now()); return getItemPromise(items[].id);
})
.then(function () {
return getItemPromise(items[].id);
})
.then(function () {
return getItemPromise(items[].id);
})
.then(function () {
return getItemPromise(items[].id);
})
.then(function () {
return getItemPromise(items[].id);
})

  这样请求得到的顺序就是相同的了。 但是通过for循环,不论分类有多少,我们都可以请求到。

也就是说,通过链式调用的方式,即.then().then()这样才会在一个异步执行完之后执行下一个,值得注意。

  

vue中promise的使用的更多相关文章

  1. vue 中promise 异步请求数据

    export function getTypes(type) { return listDictItems({ code: type }).then((res) => { if (res.cod ...

  2. vue中Promise对象用法

    Promise.all([ 需要异步一起执行的方法---------先做的事 ]).then(res=>{ 后做的事(先做的事已经做好了) }) 举栗子: Promise.all([ this. ...

  3. Vue中之nextTick函数源码分析

    Vue中之nextTick函数源码分析 1. 什么是Vue.nextTick()?官方文档解释如下:在下次DOM更新循环结束之后执行的延迟回调.在修改数据之后立即使用这个方法,获取更新后的DOM. 2 ...

  4. axios在vue中的简单配置与使用

    一.axios 简介 axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,它本身具有以下特征:https://hzzly.github.io/2017/03/12/ ...

  5. 【转】简单理解Vue中的nextTick

    前言: Vue中的nextTick涉及到Vue中DOM的异步更新,感觉很有意思,特意了解了一下.其中关于nextTick的源码涉及到不少知识,很多不太理解,暂且根据自己的一些感悟介绍下nextTick ...

  6. 简单理解Vue中的nextTick

    Vue中的nextTick涉及到Vue中DOM的异步更新,感觉很有意思,特意了解了一下.其中关于nextTick的源码涉及到不少知识,很多不太理解,暂且根据自己的一些感悟介绍下nextTick. 一. ...

  7. vue中的跨域问题

    https://segmentfault.com/a/1190000011072725(原文)   使用vue-axios和vue-resource解决vue中调用网易云接口跨域的问题 注(api很重 ...

  8. 在vue中使用import()来代替require.ensure()实现代码打包分离

    最近看到一种router的写法 import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) const login = ...

  9. vue中Axios的封装和API接口的管理

    前端小白的声明: 这篇文章为转载:主要是为了方便自己查阅学习.如果对原博主造成侵犯,我会立即删除. 转载地址:点击查看 如图,面对一团糟代码的你~~~真的想说,What F~U~C~K!!! 回归正题 ...

随机推荐

  1. 博客迁移到http://pengliu.cf

    博客迁移到http://pengliu.cf

  2. 解决"要执行请求的操作,WordPress需要访问您网页服务器的权限"

    比如我们在VPS主机中创建WordPress站点的时候,会有需要在线安装主题.插件等,但是点击下载安装的时候会有"要执行请求的操作,WordPress需要访问您网页服务器的权限. 请输入您的 ...

  3. Windows实用功能

    查看程序crash日志:"Computer Management"-"System Tools"-"Event Viewer"-" ...

  4. 微信 oauth2 两次回调

    场景: logger.Info("f: " + wx.From); logger.Info("c: " + wx.Code); logger.Info(&quo ...

  5. day4学python 字符编码转换+元组概念

    字符编码转换+元组概念 字符编码转换 #coding:gbk //此处必声明 文件编码(看右下角编码格式) #用来得到python默认编码 import sys print(sys.getdefaul ...

  6. 20165219 《Java程序设计》实验三(敏捷开发与XP实践)实验报告

    20165219 <Java程序设计>实验三(敏捷开发与XP实践)实验报告 一.实验报告封面 课程:Java程序设计 班级:1652班 姓名:王彦博 学号:20165219 成绩: 指导教 ...

  7. 标准模板库使用参考——vector向量容器

    C++的STL从广义上讲分为algorithm(算法),container(容器)和iterator(迭代器)三类,包含了诸多在计算机科学领域里所常用的基本数据结构和基本算法. 在C++标准库中,ST ...

  8. 网页控件很多时最好用绝对定位absolute

    否则动一个位置可能影响其他的,牵一发而动全身

  9. blog搬家须知

    我的博客即将入驻“云栖社区”,诚邀技术同仁一同入驻. 地址:这里. 不过这里也是会同步更新的

  10. python创建virtualenv虚拟环境

    pip install virtualenv virtualenv env_py36_crawl env_py36_crawl\Scripts\activate deactivate pip free ...