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


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 相关文章推荐
Code:findPosX 和 findPosY
Dec 20 Javascript
document.getElementById介绍
Sep 13 Javascript
JS小功能(列表页面隔行变色)简单实现
Nov 28 Javascript
JavaScript中匿名函数用法实例
Mar 23 Javascript
使用jQuery mobile库检测url绝对地址和相对地址的方法
Dec 04 Javascript
正则表达式(语法篇推荐)
Jun 24 Javascript
深入理解Node中的buffer模块
Jun 03 Javascript
Require.js的基本用法详解
Jul 03 Javascript
AngularJS实现表格的增删改查(仅限前端)
Jul 04 Javascript
JS路由跳转的简单实现代码
Sep 21 Javascript
vue选项卡切换登录方式小案例
Sep 27 Javascript
微信小程序封装多张图片上传api代码实例
Dec 30 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编程最快明白(第一讲 软件环境和准备工作)
2010/10/25 PHP
DEDE采集大师官方留后门的删除办法
2011/01/08 PHP
学习php分页代码实例
2013/10/24 PHP
ThinkPHP学习笔记(一)ThinkPHP部署
2014/06/22 PHP
Laravel推荐使用的十个辅助函数
2019/05/10 PHP
使一个函数作为另外一个函数的参数来运行的javascript代码
2007/08/13 Javascript
比较简单实用的使用正则三种版本的js去空格处理方法
2007/11/18 Javascript
使用phantomjs进行网页抓取的实现代码
2014/09/29 Javascript
使用canvas实现仿新浪微博头像截取上传功能
2015/09/02 Javascript
深入浅析JavaScript函数前面的加号和叹号
2016/07/09 Javascript
一个非常好用的文字滚动的案例,鼠标悬浮可暂停[两种方案任选]
2016/12/01 Javascript
三种方式实现瀑布流布局
2017/02/10 Javascript
Swiper实现轮播图效果
2017/07/03 Javascript
基于zepto.js实现登录界面
2017/10/09 Javascript
基于vue+axios+lrz.js微信端图片压缩上传方法
2019/06/25 Javascript
vue项目打包之开发环境和部署环境的实现
2020/04/23 Javascript
vue 解决addRoutes多次添加路由重复的操作
2020/08/04 Javascript
python学习笔记之调用eval函数出现invalid syntax错误问题
2015/10/18 Python
Python 实现数据库(SQL)更新脚本的生成方法
2017/07/09 Python
Python 函数返回值的示例代码
2019/03/11 Python
python买卖股票的最佳时机(基于贪心/蛮力算法)
2019/07/05 Python
python实现批量nii文件转换为png图像
2019/07/18 Python
django基于存储在前端的token用户认证解析
2019/08/06 Python
Django模板之基本的 for 循环 和 List内容的显示方式
2020/03/31 Python
使用tensorflow框架在Colab上跑通猫狗识别代码
2020/04/26 Python
JAVA及PYTHON质数计算代码对比解析
2020/06/10 Python
浅析Python 责任链设计模式
2020/09/11 Python
巴西食品补充剂在线零售商:Músculos na Web
2017/08/07 全球购物
大学生年度自我鉴定
2013/10/31 职场文书
法学毕业生自荐信
2013/11/13 职场文书
婚前财产公证书
2014/04/10 职场文书
优秀教师个人总结
2015/02/11 职场文书
2015社区爱国卫生工作总结
2015/04/21 职场文书
房屋租赁意向书范本
2015/05/09 职场文书
2016年社区“6.26”禁毒日宣传活动总结
2016/04/05 职场文书
Python合并pdf文件的工具
2021/07/01 Python