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. Linq 左连接 left join

    Suppose you have a tblRoom and tblUserInfo. Now, you need to select all the rooms regardless of whet ...

  2. ASP.NET Session原理及处理方法

    session是怎么存储,提取的 1.在服务器端有一个session池,用来存储每个用户提交session中的数据,Session对于每一个客户端(或者说浏览器实例)是“人手一份”,用户首次与Web服 ...

  3. CentOS 用户/组与权限

    useradd:添加用户 useradd abc,默认添加一个abc组 vipw:查看系统中用户 groupadd:添加组groupadd ccna vigr:查看系统中的组 gpasswd:将用户a ...

  4. C# 操作 MongoDB

    今项目使用Mongodb,C#操作MongoDB使用MongoDB.Driver.dll库(Nuget),写了个小Demo,如下: using System; using System.Collect ...

  5. WM_QUERYENDSESSION与WM_ENDSESSION

    此文已由作者王荣涛授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 首先XP系统和Vista以后的系统,这两个消息的处理方式是不同的. XP系统 系统发送WM_QUERYEND ...

  6. StringUtils常用方法介绍

    要使用StringUtils类,首先需要导入:import org.apache.commons.lang.StringUtils;这个包 在maven项目中需要添加下面这个依赖: <depen ...

  7. linux 改变系统时间

    date  查看系统时间 date -s 04/05/16  日期设置成2016年4月5日 date -s 15:03:32  日期设置成2016年4月5日15:03:32 上述两步可以直接写成这样一 ...

  8. curl下载目录

    http://ftp.loongnix.org/os/loongnix/1.0/SRPMS/ wget wget -c -r -np -k -L -p

  9. Unity性能优化专题---腾讯牛人分享经验

    这里从三个纬度来分享下内存的优化经验:代码层面.贴图层面.框架设计层面. 一.代码层面. 1.foreach. Mono下的foreach使用需谨慎.频繁调用容易触及堆上限,导致GC过早触发,出现卡顿 ...

  10. python3好用的requests库

    python3好用的requests库 requests是什么? requests是基于urllib编写的http库,支持python3,比urllib更好用,更简单.之前使用python写一些htt ...