为AJAX请求进行回调以将响应返回给调用者

时间:2017-03-29 00:05:19

标签: javascript ajax callback

我到处都看了,我找到的答案都没能帮我解决这个问题。基本上我有一个函数调用一个单独的函数来生成XMLHttpRequest。请求转到服务器,服务器生成一个随机数并将其返回到页面。

问题在于,当请求正在获取数据时,调用者函数会继续执行其命令。我需要在调用者可以继续之前获取请求中的数据。人们已经提到了回调和承诺,我都无法用网上的内容来掌握这些回调和承诺。我宁愿使用回调,因为并非所有浏览器都支持promises。有人可以帮我找一下如何使用它们吗?如果需要,我可以提供一些代码。

这是我的来电者功能:

function plotData(dataSet) 
{   
var x = xScale+20; // 20 = margin length
var y = 260;    //origin of graph

getRequest();
console.log("x = "+x);  
console.log("dataSet = "+dataSet[0]+", "+dataSet[1]); 
... //rest of the function commands
}

这是我的XML请求:

function getRequest()
{
var request;

if (window.XMLHttpRequest) 
{ // Mozilla, Safari, IE7+ ...
    request = new XMLHttpRequest();
} 
else if (window.ActiveXObject) 
{ // IE 6 and older
    request = new ActiveXObject("Microsoft.XMLHTTP");
}   
    request.onreadystatechange = function()
    {   
        console.log('onReady');
        if (request.readyState === XMLHttpRequest.DONE)
        {
            if (request.status === 200)
            {
                random = request.responseText;
                random = parseInt(random);
                random = random/100;
                random = random.toFixed(2);
                console.log("random = " +random);
                data[1] = random;
                console.log("data = "+data[0]+", "+data[1]);
            }
        else
        {
            alert ('There was a problem with the request');
        }

        }
}   
request.open("GET", "lak1010_hw05.php", true);
request.send();     
}

4 个答案:

答案 0 :(得分:1)

承诺是前往这里的方式。您可以使用Promise polyfill来帮助处理不受支持的浏览器。

var myPromise = (function() {
    return new Promise(function(resolve, reject) {
        $.ajax({
            url:'/page.php?id=123',
            type:'POST',
            success: function(data) {
                resolve(data);
            }
        });
    });
})();
myPromise.then(function(data) {
  // Continue code here
});

基本上,您创建一个使用AJAX调用返回的数据解析的promise。当Promise解决后,myPromise.then()会被触发,并且您使用在promise解析中传递的数据继续执行代码。如果AJAX错误或数据无效等,您还可以reject()承诺。

使用您的代码:

function plotData(dataSet) 
{   
var x = xScale+20; // 20 = margin length
var y = 260;    //origin of graph
var myPromise = new Promise(function(resolve, reject) {
    $.ajax({
        url:'/page.php?id=123',
        type:'POST',
        success: function(dataSet) {
            resolve(dataSet);
        }
    });
});

myPromise.then(function(dataSet) {
    console.log("x = "+x);  
    console.log("dataSet = "+dataSet[0]+", "+dataSet[1]); 
    ... //rest of the function commands
});


}

仅使用回调更简单:

function plotData(dataSet) 
{   
var x = xScale+20; // 20 = margin length
var y = 260;    //origin of graph

    $.ajax({
        url:'/page.php?id=123',
        type:'POST',
        success: function(dataSet) {
            console.log("x = "+x);  
            console.log("dataSet = "+dataSet[0]+", "+dataSet[1]); 
            ... //rest of the function commands
        }
    });

}

答案 1 :(得分:1)

编辑:好吧,我错过了你的编辑,并认为这只是一个普遍的承诺问题。

这是一个带参数的函数:

test = function(parameter) {
  if (paramater) {
    return true
  } else {
    return false
  }
}

这是一个具有额外参数的函数,称为“回调”。

test = function(parameter, callback) {
  if (parameter) {
    callback(null, 'result')
  } else {
    callback('error')
  }
}

回调通常有两个参数。错误和可选结果。

如您所见,如果参数为true,我们运行一个函数,返回'null'作为错误,并将'result'作为结果。

如果你想使用回调来延迟函数,你只需调用这个函数:

test(true, function(err, result) {
  if(err) {
    console.log(err)
  } else {
    console.log(result)
  }
})

将console.log替换为成功结果或错误时所需的函数。一开始很难理解,但是尝试为它编写一些代码 - 当你没有根深蒂固的异步代码概念时,读取通常是无用的。

你必须手动添加回调和东西 - 这是我后端的摘录。

this.findOneByPhone = function(phone, req, res, callback) {
        connection.acquire(function(err, con) {
            con.query('select * from users where phone = ?', [phone], function(err, result) {
                con.release()
                if (err) {
                    callback(err)
                } else {
                    callback(null, JSON.stringify(result[0], null, 4))
                }
            })
        })
    }

然后调用它;

this.findOneByPhone(user.phone, null, null, function(err, foundUser) {
                if (err) {
                    res.status(500).json({message: 'Signup findOneByPhone failed.', error: err})
                } else {
                    if (foundUser) {
                        var foundUserJSON = JSON.parse(foundUser)
                        res.json({status: 0, message: 'User already found in database, please skip signup', result: 'skip'})
                    } else {
                        res.json({status: 0, message: 'User is not in database, please signup', result: 'signup'})
                    }
                }
            })

答案 2 :(得分:1)

尝试使用新的fetch API。使用jQuery的承诺非常破碎:/

=> https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

    var myHeaders = new Headers();

    var myInit = { method: 'GET',
                   headers: myHeaders,
                   mode: 'cors',
                   cache: 'default' };

    fetch('flowers.jpg', myInit)
    .then(function(response) {
      return response.blob();
    })
    .then(function(myBlob) {
      var objectURL = URL.createObjectURL(myBlob);
      myImage.src = objectURL;
    });

答案 3 :(得分:1)

以下是您使用回调修改后的getRequest函数

function getRequest(callback)
{
var request;

if (window.XMLHttpRequest) 
{ // Mozilla, Safari, IE7+ ...
    request = new XMLHttpRequest();
} 
else if (window.ActiveXObject) 
{ // IE 6 and older
    request = new ActiveXObject("Microsoft.XMLHTTP");
}   
    request.onreadystatechange = function()
    {   
        console.log('onReady');
        if (request.readyState === XMLHttpRequest.DONE)
        {
            if (request.status === 200)
            {
                random = request.responseText;
                random = parseInt(random);
                random = random/100;
                random = random.toFixed(2);
                console.log("random = " +random);
                data[1] = random;
                console.log("data = "+data[0]+", "+data[1]);
                // here call your callback
                callback(random);
            }
        else
        {
            alert ('There was a problem with the request');
        }

        }
}   
request.open("GET", "lak1010_hw05.php", true);
request.send();     
}

您的通话方式,

function plotData(dataSet) 
{   
var x = xScale+20; // 20 = margin length
var y = 260;    //origin of graph

getRequest(function(random){
   console.log('Random number received:');
   console.log(random);
});
console.log("x = "+x);  
console.log("dataSet = "+dataSet[0]+", "+dataSet[1]); 
... //rest of the function commands
}