Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ajax请求序列化问题 #29

Open
jirengu opened this issue Feb 19, 2017 · 5 comments
Open

ajax请求序列化问题 #29

jirengu opened this issue Feb 19, 2017 · 5 comments

Comments

@jirengu
Copy link
Owner

jirengu commented Feb 19, 2017

某个应用模块由文本框 input,以及按钮 A,按钮 B 组成。点击按钮 A,会向地址 urlA 发出一个 ajax 请求,并将返回的字符串填充到 input 中(覆盖 input 中原有的数据),点击按钮 B,会向地址 urlB 发出一个 ajax 请求,并将返回的字符串填充到 input 中(覆盖 input 中原有的数据)。

当用户依次点击按钮 A、B 的时候,预期的效果是 input 依次被 urlA、urlB 返回的数据填充,但是由于到 urlA 的请求返回比较慢,导致 urlB 返回的数据被 urlA 返回的数据覆盖了,与用户预期的顺序不一致。

请问如何设计代码,解决这个问题? ——题目来自知乎

@jirengu
Copy link
Owner Author

jirengu commented Feb 19, 2017

    buttonA.onclick = function(){
      get('/a', function(resTxt){
        console.log(resTxt)
        input.value = resTxt
      })
    }

    buttonB.onclick = function(){
      get('/b', function(resTxt){
        console.log(resTxt)
        input.value = resTxt
      })
    }


    function get(url, callback){
      
      if(!Array.isArray(get.xhrQueue)){
        get.xhrQueue = []
      }
      var xhrQueue = get.xhrQueue
      var xhr  = new XMLHttpRequest()
      xhrQueue.push(xhr)
      xhr.opts = {}
      xhr.onloadend = function(){
        this.opts.finished = true
        checkQueue()
      }

      xhr.opts.finished = false
      xhr.opts.callback = callback
      xhr.timeout = 1000*8
      xhr.open('get', url, true)
      xhr.send()
      
      function checkQueue(){
        var xhr = xhrQueue[0]
        while(xhr && xhr.opts.finished){
          if(xhr.status == 200 || xhr.status == 304){
            xhr.opts.callback(xhr.responseText)
          }
          xhrQueue.shift()
          xhr = xhrQueue[0]
        }

      }
    }

@LiuL0703
Copy link

这个问题是不是也可以用Promise 解决

@Inori-Lover
Copy link

不是应该把第二个的填充放到第一个填充函数的callback?(所以也可以promise?

@ke1vin4real
Copy link

核心是队列的思想

@zzz945
Copy link

zzz945 commented Mar 19, 2018

es6伪代码, 忽略细节和错误处理

let input = findInputElement()
let aPromise

function onButtonAClick () {
  aPromise = api.getA().then(text => input.value = text)
}

async function onButtonBClick () {
  await aPromise
  input.value = await api.getB()
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants