小程序关于请求同步的总结


Posted in Javascript onMay 05, 2019

在JavaScript中,提供了一些异步特性,因为同步操作会对程序的执行进行阻塞处理。比如在浏览器页面程序中,如果一段同步的代码需要执行很长时间(比如一个很大的循环操作),则页面会产生卡死的现象。

异步为程序提供了性能和体验上的益处,比如可以将代码放到setTimeout()中执行;或者在网页中,我们使用Ajax的方式向服务器端做异步数据请求。这些异步的代码不会阻塞当前的界面主进程,界面还是可以灵活的进行操作,等到异步代码执行完成,再做相应的处理。

举一个例子:在小程序中,我们获取到后台的数据使用时间往往是不定的,这个时候:即使你在前面写的代码,也可能会在后面执行。

function getAccountInfo(callback, errorCallback) {
 wx.request({
 url: '/accounts/12345',
 success: function (res) {
  console("1") },
 fail: function (res) {
  //...
  errorCallback(data);
 }
 });
console.log("2")
}

也就是存在2输出在1前面的可能。这种策略提升页面加载速度。能很好的提高用户体验感。

但是请看下面的情景:

小程序是提倡不获取用户信息就能使用的,但是在特定的情况下我们必须要拿到用户的一些数据,比如名称,图像链接等等。在这种情况下,我们首先获取用户的code,根据code去后台获取用户的openid或者unionid。拿到这些数据之后我们才能确定用户的身份,然后再去发新的请求(这些请求往往是需要用户身份凭证的,比如Token)。

上面的叙述中,我们发了三次请求,第一次获取code,第二次获取openID或unionid,第三次根据身份信息执行新的请求。我们都知道JS中的请求都是异步执行的,有可能微信服务端的code还没返回,用户已经去执行一些需要权限的操作,这就会导致请求失败。那么小程序该如何解决这种问题呢?这里提供三种方案以供参考:

1.服务端一次请求全部处理。(使用范围太小)

2.客户端在请求成功的回调中,再次发送请求。(可用,但是代码会很冗长且不容易维护)

3.使用Promise

方案一中:比如用户留言功能,我们拿到code和留言内容后全部发给服务端,服务端开启一个新的线程去处理这些业务逻辑,主线程直接返回用户留言成功的提示(这里不考虑新线程执行失败的情况)。

方案二和方案三功能上是相同的,但是代码的展示上可能方案三更加好一些。看下面的代码(其中postReq和getReq是自己封装的请求方法):

var http = require('request.js')
function userLogin(name, image, gender, content, artilceId){
 //获取code
 var promise = new Promise(function(resolve,reject){
 wx.login({
  success: res => {
  resolve(res.code);
  }
 })
 })
 //获取用户身份凭证
 var pm2 = promise.then(function(res){
 return new Promise(function (resolve, reject){
  http.postReq("user/getUserInfo", { "code": res, "type": 1, "name": name, "image": image, "gender": gender }, function (res) {
  // console.log(res)
  if (res.data == "") {
   wx.showModal({
   title: '提示',
   content: '授权失败,请重试',
   })
   return;
  }
  resolve(res);
  })
 })
 },function(res){
 
 })
 //发表评论
 pm2.then(function(res){
 // console.log(res.data+":"+content)
 http.postReq("user/comment", { "content": content, "openId": res.data, "artilceId": artilceId},function(res){
  // console.log(res)
  if(res.data ){
  wx.getStorage({
   key: 'showInfo',
   success: function(res) {
   console.log(res.data )
   if(res.data != false){
    wx.showModal({
    title: '提示',
    content: '为了维护每天学Java的学习氛围,我们已发邮件提醒管理员对评论进行审核,通过后即可展示您的评论。',
    })
   }
   },fail:function(res){
   wx.setStorage({
    key: 'showInfo',
    data: false,
   })
   wx.showModal({
    title: '提示',
    content: '为了维护每天学Java的学习氛围,我们已发邮件提醒管理员对评论进行审核,通过后即可展示您的评论。',
   })
   }
  })
 
  }
 
  })
 },
 function(res){
  })
}
 
module.exports = {
 userLogin: userLogin
}

 这里使用的就是Promise?对于Promise如何使用我们稍后再说,初学阶段我们可能会这样保证同步:

app.postReq("/homework/getHomeWorkLike",{"name":name},function(res){
  app.postReq("/homework/getHomeWorkLike",{"name":name},function(res){
   app.postReq("/homework/getHomeWorkLike",{"name":name},function(res){
 
      }
     })
    }
   })
  }
 })

在每次返回成功的回调中执行新的请求,但是当我们处理的业务逻辑过多时候,就会显得很难看。因为不直观,所以不方便我们排查一些错误。所以推荐大家使用Promise。

Promise :

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。

所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

Promise对象有以下两个特点。

(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。

(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

注意,为了行文方便,本章后面的resolved统一只指fulfilled状态,不包含rejected状态。

有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操作更加容易。

Promise也有一些缺点。首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。第三,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

如果某些事件不断地反复发生,一般来说,使用 Stream 模式是比部署Promise更好的选择。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js AspxButton的客户端操作
Jun 26 Javascript
jquery 添加节点的几种方法介绍
Sep 04 Javascript
jQuery学习笔记之 Ajax操作篇(三) - 过程处理
Jun 23 Javascript
angularjs中的单元测试实例
Dec 06 Javascript
js基于面向对象实现网页TAB选项卡菜单效果代码
Sep 09 Javascript
js 定义对象数组(结合)多维数组方法
Jul 27 Javascript
laydate 显示结束时间不小于开始时间的实例
Aug 11 Javascript
AngularJS中scope的绑定策略实例分析
Oct 30 Javascript
使用express+multer实现node中的图片上传功能
Feb 02 Javascript
在vue中使用css modules替代scroped的方法
Mar 10 Javascript
使用jQuery mobile NuGet让你的网站在移动设备上同样精彩
Jun 18 jQuery
element-ui中el-upload多文件一次性上传的实现
Dec 02 Javascript
vue列表单项展开收缩功能之this.$refs的详解
May 05 #Javascript
小程序异步问题之多个网络请求依次执行并依次收集请求结果
May 05 #Javascript
深入解析Vue源码实例挂载与编译流程实现思路详解
May 05 #Javascript
Vue 中如何正确引入第三方模块的方法步骤
May 05 #Javascript
详解vue的双向绑定原理及实现
May 05 #Javascript
Vue+Express实现登录注销功能的实例代码
May 05 #Javascript
Vue 递归多级菜单的实例代码
May 05 #Javascript
You might like
PHP.MVC的模板标签系统(四)
2006/09/05 PHP
十天学会php之第十天
2006/10/09 PHP
php实现cc攻击防御和防止快速刷新页面示例
2014/02/13 PHP
yii2整合百度编辑器umeditor及umeditor图片上传问题的解决办法
2016/04/20 PHP
php简单随机字符串生成方法示例
2017/04/19 PHP
js静态作用域的功能。
2006/12/25 Javascript
javascript算法题 求任意一个1-9位不重复的N位数在该组合中的大小排列序号
2012/07/21 Javascript
input 输入框获得/失去焦点时隐藏/显示文字(jquery版)
2013/04/02 Javascript
JQuery页面图片切换和新闻列表滚动效果的具体实现
2013/09/26 Javascript
JQuery中操作Css样式的方法
2014/02/12 Javascript
IE6-8中Date不支持toISOString的修复方法
2014/05/04 Javascript
JavaScript设计模式之策略模式实例
2014/10/10 Javascript
javascript 判断两个日期之差的示例代码
2015/09/05 Javascript
封装获取dom元素的简单实例
2016/07/08 Javascript
node.js实现微信JS-API封装接口的示例代码
2017/09/06 Javascript
Vue使用json-server进行后端数据模拟功能
2018/04/17 Javascript
nodeJs爬虫的技术点总结
2018/05/13 NodeJs
vue-music 使用better-scroll遇到轮播图不能自动轮播问题
2018/12/03 Javascript
vue中axios防止多次触发终止多次请求的示例代码(防抖)
2020/02/16 Javascript
使用pandas read_table读取csv文件的方法
2018/07/04 Python
解决pandas中读取中文名称的csv文件报错的问题
2018/07/04 Python
Python神奇的内置函数locals的实例讲解
2019/02/22 Python
Python循环实现n的全排列功能
2019/09/16 Python
python代码如何实现余弦相似性计算
2020/02/09 Python
tensorflow图像裁剪进行数据增强操作
2020/06/30 Python
HTML5在canvas中绘制复杂形状附效果截图
2014/06/23 HTML / CSS
借助HTML5 Canvas API制作一个简单的猜字游戏
2016/03/25 HTML / CSS
Coach澳大利亚官方网站:美国著名时尚奢侈品牌
2017/05/24 全球购物
Myprotein比利时官方网站:欧洲第一运动营养品牌
2020/10/04 全球购物
竞选劳动委员演讲稿
2014/04/28 职场文书
文明家庭先进事迹材料
2014/05/14 职场文书
厕所文明标语
2014/06/11 职场文书
法制宣传标语集锦
2014/06/25 职场文书
党员贯彻十八大精神思想汇报范文
2014/10/25 职场文书
2014年检验员工作总结
2014/11/19 职场文书
2016年“5.12”护士节致辞
2015/07/31 职场文书