vue中promise的使用
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的使用的更多相关文章
- vue 中promise 异步请求数据
export function getTypes(type) { return listDictItems({ code: type }).then((res) => { if (res.cod ...
- vue中Promise对象用法
Promise.all([ 需要异步一起执行的方法---------先做的事 ]).then(res=>{ 后做的事(先做的事已经做好了) }) 举栗子: Promise.all([ this. ...
- Vue中之nextTick函数源码分析
Vue中之nextTick函数源码分析 1. 什么是Vue.nextTick()?官方文档解释如下:在下次DOM更新循环结束之后执行的延迟回调.在修改数据之后立即使用这个方法,获取更新后的DOM. 2 ...
- axios在vue中的简单配置与使用
一.axios 简介 axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,它本身具有以下特征:https://hzzly.github.io/2017/03/12/ ...
- 【转】简单理解Vue中的nextTick
前言: Vue中的nextTick涉及到Vue中DOM的异步更新,感觉很有意思,特意了解了一下.其中关于nextTick的源码涉及到不少知识,很多不太理解,暂且根据自己的一些感悟介绍下nextTick ...
- 简单理解Vue中的nextTick
Vue中的nextTick涉及到Vue中DOM的异步更新,感觉很有意思,特意了解了一下.其中关于nextTick的源码涉及到不少知识,很多不太理解,暂且根据自己的一些感悟介绍下nextTick. 一. ...
- vue中的跨域问题
https://segmentfault.com/a/1190000011072725(原文) 使用vue-axios和vue-resource解决vue中调用网易云接口跨域的问题 注(api很重 ...
- 在vue中使用import()来代替require.ensure()实现代码打包分离
最近看到一种router的写法 import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) const login = ...
- vue中Axios的封装和API接口的管理
前端小白的声明: 这篇文章为转载:主要是为了方便自己查阅学习.如果对原博主造成侵犯,我会立即删除. 转载地址:点击查看 如图,面对一团糟代码的你~~~真的想说,What F~U~C~K!!! 回归正题 ...
随机推荐
- 加载 页面 中js 方法
js 文件中 var mingchen= mingchen|| { init: function (){ } }; 文件中 mingchen.init(); 注意问题: 在新加载 页面中 ...
- <%@ include > 与< jsp:include >
include指令表示在JSP编译时插入一个包含文本或者代码的文件,把文件中的文本静态地包含过去.也就是说,会把被包含的页面拷贝到包含的页面中指令所在的位置. 语法格式:<%@ include ...
- 门面(Facade)模式
门面(Facade)模式 也叫 外观模式. 外观模式:为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得子系统更加容易使用 /* * 门面(Facade)角色:客户端可以 ...
- springcloud提供开放api接口签名验证
一.MD5参数签名的方式 我们对api查询产品接口进行优化: 1.给app分配对应的key.secret 2.Sign签名,调用API 时需要对请求参数进行签名验证,签名方式如下: a. 按照请求参数 ...
- Jquery 页面元素事件绑定
场景: 用一个Table来展示数据信息列表,通过鼠标点击Table中的Tr来获取到当前选中的数据行信息. <table class="Table" width="1 ...
- C语言#include的用法
1.#include 命令介绍 #include 命令是预处理命令的一种,预处理命令可以将别的源代码内容插入到所指定的位置:可以标识出只有在特定条件下才会被编译的某一段程序代码: 可以定义类似标识符功 ...
- 【FAQ】服务下线
原因:磁盘已满
- (C/C++) Link List - C++ 版本
利用C++寫一個基本的 Link list 練習,功能包含 pint list.CreatList.Insert.Delete.Reverse.Search.Clear.GetLen. 先建立相關的C ...
- GCD BZOJ2818 [省队互测] 数学
题目描述 给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对. 输入输出格式 输入格式: 一个整数N 输出格式: 答案 输入输出样例 输入样例#1: 复制 4 ...
- Nuclear Power Plant ZOJ - 3840 树形dp
There are N (1 ≤ N ≤ 105) cities on land, and there are N - 1 wires connecting the cities. Therefore ...