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. Git教程--廖雪峰

    Git简介 1.Git是目前世界上最先进的分布式版本控制系统(没有之一) 2.集中式和分布式版本控制系统有什么区别呢?      区别在于历史版本维护的位置:Git本地仓库包含代码库还有历史库,在本地 ...

  2. python 测试报告发送邮件

    使用过程成出现的如下错误 smtplib.SMTPDataError: (554, 'DT:SPM 126 smtp5错误解决办法   1.自动化测试中,调用邮件模块自动发送邮件时,运行脚本报错: s ...

  3. CSS3的2D与3D转换

    2D和3D转换涉及到数学中的知识,作为一个数学专业的毕业生,不研究一下岂不是对不起自己的专业? 首先来看几个参数: 1.transform-origin:origin(起源,起点),也即变形的起点,在 ...

  4. C# -- 泛型(1)

    简介: 先看看泛型的概念--“通过参数化类型来实现在同一份代码上操作多种数据类型.利用“参数化类型”将类型抽象化,从而实现灵活的复用”. 很多初学者在刚开始接触泛型的时候会比较难理解 “泛型” 在这里 ...

  5. C# HTML转EXCEL的方法

    private void ToExcel(string html) { Response.ContentType = "application/force-download"; R ...

  6. day2学python 数据类型+深浅拷贝+循环

    数据类型+深浅拷贝+循环 别的语言的数组 python不用定义 直接使用 color=['红','橙','黄','绿','青','蓝','紫'] print(color[1:3]) //打印[1,3) ...

  7. 查看linux操作系统的版本等信息

    1.查看操作系统是32位还是64位的命令: (1)getconf LONG_BIT (2)uname -a (3)uname -m (4)arch (5)file /sbin/init 2.查看操作系 ...

  8. vscode 遇到设置问题

    // 控制是否在新窗口中打开文件. // - default: 除了从软件内部选择的文件 (如,从“文件”菜单选择),其他所有文件都将在新窗口中打开 // - on: 文件将在新窗口中打开 // - ...

  9. mfix mpi并行死锁问题探究

    目前还没找到具体原因,只能先记录一下.(问题原因找到了) 分别用ubuntu14.04和ubuntu16.04测试,用的是笔记本,笔记本为双核四线程,用2线程并行计算:发现ubuntu16.04会在0 ...

  10. 【原创】SpringMVC同一RequestMapping返回不同的类型

    曾经在工作中遇到过导出文件时,需要根据不同情况返回不同的数据的情况. 例如: 如果没有数据,弹框提示"没有数据" 导出报错,弹框提示"系统错误" 正常情况下,下 ...