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. 20169219 使用Metaspoit攻击MS08-067实验报告

    MS08-067漏洞介绍 MS08-067漏洞的全称为"Windows Server服务RPC请求缓冲区溢出漏洞",如果用户在受影响的系统上收到特制的 RPC 请求,则该漏洞可能允 ...

  2. springMVC传对象参数

    springController: [java] view plaincopy @Controller @RequestMapping("/user") public UserCo ...

  3. 从后台传select的值

    var option = ''; $.each(data, function (i, v) { option += "<option value='" + i + " ...

  4. kafka启动报错Cannot allocate memory;There is insufficient memory for the Java Runtime Environment to continue.

    kafka启动过程报错,配置没有问题,这就懵了!! Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000 ...

  5. Atcoder Grand Contest 031B(DP,思维)

    #include<bits/stdc++.h>using namespace std;int a[200007];int b[200007];long long dp[200007];lo ...

  6. Mysql高性能优化规范建议

    数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用mysql保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名识意 ...

  7. winform列标题高度无法改变

    datagridview行为里把ColumnHeadersHeightSizeMode属性设置为EnableResizing 但好像会导致横向滚动条从底部跑到了中间,还不知道这个BUG的原因,将Col ...

  8. VS2010 UAC执行级别修改

    配置属性 -> 链接器 -> 清单文件 -> UAC执行级别 改为 requireAdministrator 这个级别即可.

  9. HDU6318-2018ACM暑假多校联合训练2-1010-Swaps and Inversions-树状数组

    本题题意是,给你一个长度为n的序列,使用最少的操作把序列转换为从小到大的顺序,并输出操作数*min(x,y) 实质上是算出该序列中有多少逆序对,有归并排序和树状数组两种算法,由于数据之间的差值有点大, ...

  10. linux系统安全及应用——PAM安全认证

    一.PAM认证模块介绍 PAM认证模块,叫做可插拔式的认证模块.一项重要的功能就是为了加强su命令的使用控制,可以借助于PAM认证模块,只允许极个别用户使用su命令进行切换.PAM提供了对所有服务进行 ...