回调地狱的解决办法

回调是地狱是容易遇到的坑,解决方案是使用promise

碎碎念

相信各位玩家肯定都写过下面的这样代码:


// 同时发送两个请求
let url = 'xxxxx', url1 = 'xx'
$.ajax({
  url,
  success(data) {
    $.ajax({
       url: url1,
       success(data) {
          console.log('done')
       }
    })
  }
})

是不是很贴切?
有可能有的新手小伙伴连回调都不知道,这里给大家普及一下

/*
** time - 时间
** call  - 回调
*/

let outTime = (time, call) => {
  setTimeout(()=> {
    call()
  }, time)
}

// 使用

outTime(2000,()=>{
  console.log('done')
})

这就是最简单最常见场景下的回调了. 在我刚学js时候,遇到一个困惑
在尝试发起请求的时候, 第一会遇到跨域请求, 还有就是不是同步代码的困惑

所谓的同步代码,给大家上一段当初我写的代码(超害羞??)

// 假设我封装了一个方法来发起`http`请求: func
let data = func({
  url: 'xxx',
  data: { path: 'xxx' }
})
console.log(data)

当打印之后永远都是undefined

诶,我就不信了

func({
  url: 'xxx',
  data: { path: 'xxx' },
  success(data) {
    window.fuck = data
  }
})
let fuckInter  = setInterval(()=> {
  if (window.fuck) next()
},50)

function next() {
  // 接下来的代码..
}

先别笑,我当初还真是这么解决的..
我尝试读了一下jq源码,发现它实现了一种所谓的callback回调函数
(很惭愧的是,现在都不能跟观众老爷们说明白这是怎么一回事)

通过这件事,让我想起我一次面试,我面的是小程序,以下对话

Ta: 小程序的网络请求不太完善,你有什么办法能够优化一下网络库,满足自己需求

Me: 写一个公共文件,写一个回调函数, 把需要的参数这些都包裹起来并封装

Ta: (内心一团乱麻..) 还有...有吗?

Me: (又说了一遍)

Ta: 那好像和微信的原生库没什么区别

被小瞧了,那货其实是想问,请求加密之类的,我说用token(你又没说功能,我怎么知道...)

解决方案

回到正题,接下来就说解决方案了
vuejs 官方推荐的 axios 就是使用 promise, 我有幸在几个项目中使用过,但是没有深究其原理

;(async ()=> {
 return new Promise(( rcv, rjt)=> {
   setTimeout(()=> {
      rcv('fuck')
   }, 5000)
 })
})()
  .then(r=> {
     console.log(r) // 'fuck'
   })

promise 接受两个参数: resolve, reject
第一个参数是操作成功,第二个是在操作错误

值得一提的,如果你打印这个对象的话,它返回的会是一个:

let pro = new Promise((rsv,rjt)=> {
   console.log('xxx')
})
console.log(pro)
/*
** Promise { pending(进行中)、fulfilled(已成功)和 rejected(已失败)}
**/

在实例创建后,你可以使用then来处理成功catch来处理操作错误
现在我们就可以使用它来重写$.ajax方法

function proAjax() {
  let url = 'xxx' // 假装存在咯
  return new Promise((rcv, rjt)=> {
    $.ajax({
      url,
      success: data => rcv(data),
      error: e=> rjt(e)
    })
  })
}
// 用法

proAjax()
  .then(r=> {
   console.log('我拿到数据了,真好')
  })
  .catch(e=> {
    throw new Error(e)
  }

为了让它更像同步代码,我们可以使用async await

async function func() {
  let data await new Promise((rcv,rjt)=> {
     $.ajax(
       url,
       success: data => rcv(data)
     )
  })
  return data
}
func()
  .then(r=> {
     console.log('拿到数据了,皮卡丘!')
  })

async 我不太能够解释这是什么,只知道它会返回一个promise,所以它有then | catch 方法,至于await 它只能在async函数里使用,它可以获取promise返回值(这里不知道怎么表达),就可以实现所谓的同步代码

报错信息也很有用哦

总结

这货解决了回调地狱, 在本篇文中并未提及在promise下的多"回调",不过在每次then下由可以return promise对象,接下来就你懂的~

拥抱新技术,拥抱开源

20190819

原文地址:https://www.cnblogs.com/kozo4/p/11379873.html

时间: 2024-11-06 21:44:25

回调地狱的解决办法的相关文章

一元云购qq互联回调地址错误解决办法

经过追踪,点击登录后调用 system/modules/api/下面的qqlogin.action.class.php 里面又调用了qq 互联php接口样例里的QC.php的QC类的方法qq_login.在QC.php 找是没有qq_login这个方法 的.因为QC类又继承了Oauth类.找到Oauth类有qq_login这个方法 ,可以打印出$callback看一下,回调地址有个?号,去Recorder.class.php里修改callback就行了. 同目录下 lib/qq/qqConnec

【转】自定义UITableViewCell控件阻挡回调不到didSelectRowAtIndexPath的解决办法

原文网址:http://blog.talisk.cn/blog/2015/09/01/uitableview-didselectrowatindexpath-cannot-be-called-tips/ 作为常用的控件,UITableView出现在了很多iOS App的各个地方,近期开发时遇到了一个问题,自定义Cell中嵌套了其他具有交互事件的控件,阻挡了Cell,导致无法回调didSelectRowAtIndexPath方法,最终得出解决办法. 一句话方案 将可能影响到Tap事件的控件的use

[Android学习笔记]ListView中含有Button导致无法响应onItemClick回调的解决办法

转自:http://www.cnblogs.com/eyu8874521/archive/2012/10/17/2727882.html 问题描述: 当ListView的Item中的控件只是一些展示类控件时(比如TextView),注册ListView的监听setOnItemClickListener之后,当点击Item时候会触发onItemClick回调. 但是,当Item中存在Button(继承于Button)的控件时,onItemClick回调不会被触发. 解决方案: 在Item的布局文件

js 利用iframe和location.hash跨域解决办法,java图片上传回调JS函数跨域

奶奶的:折腾了我二天,终于解决了!网上有很多例子. 但跟我的都不太一样,费话不多说了,上图   上代码: IE ,firefix,chrome 测试通过 js :这个主页面,部分代码, function submitUpload(id){ $("#imgSrc" + id +"").attr("alt", "图片上传中--"); var imgID = id; if(id>0){ imgID = 1; } var for

基于PROMISE解决回调地狱问题

回调地狱问题: 在使用JavaScript时,为了实现某些逻辑经常会写出层层嵌套的回调函数,如果嵌套过多,会极大影响代码可读性和逻辑,这种情况也被成为回调地狱.比如说你要把一个函数 A 作为回调函数,但是该函数又接受一个函数 B 作为参数,甚至 B 还接受 C 作为参数使用,就这样层层嵌套,人称之为回调地狱,代码阅读性非常差. 例如:要发送三个异步的请求要求前面一个请求完成之后再依次发送请求. $.ajax{ url:'url1', success:result=>{ $.ajax{ url:'

解决回调地狱问题

1.回调地狱 在使用JavaScript时,为了实现某些逻辑经常会写出层层嵌套的回调函数,如果嵌套过多,会极大影响代码可读性和逻辑,这种情况也被成为回调地狱.比如说你要把一个函数 A 作为回调函数,但是该函数又接受一个函数 B 作为参数,甚至 B 还接受 C 作为参数使用,就这样层层嵌套,人称之为回调地狱,代码阅读性非常差.比如: var sayhello = function (name, callback) { setTimeout(function () { console.log(nam

js中promise解决callback回调地狱以及使用async+await异步处理的方法

1.callback回调地狱 function ajax(fn) { setTimeout(()=> { console.log('你好') fn() }, 1000) } ajax(() => { console.log('执行结束') ajax(()=>{ console.log('执行结束') ajax(()=>{ console.log('执行结束') ajax(()=>{ console.log('执行结束') }) }) }) }) 2.promise解决回调地狱

async + promise 解决回调地狱

// 解决异步回调地狱的方案: async + promise async function writeFile() { // 打开文件 const fd = await new Promise((resolve, reject) => { // 执行 打开文件 异步操作 fs.open('c.txt', 'w', (err) => { if (!err) { // 将promise对象的状态改成 成功状态 resolve(); } else { // 将promise对象的状态改成 失败状态

回调地狱以及用promise怎么解决回调地狱

哈哈哈,我又又又回来了,不好意思,最近枸杞喝的比较到位,精力比较旺盛. 现在我们来聊一聊啥是回调地狱,注意是回调地狱啊   不是RB人民最爱拍的那啥地狱啊,来吧,上车吧少年,这是去幼儿园的车 都让开,我要上高清无码大图了啊,青少年注意避让 原文地址:https://www.cnblogs.com/suihang/p/9595548.html