【问题标题】:How to make ajax call inside forEach loop [duplicate]如何在forEach循环内进行ajax调用[重复]
【发布时间】:2017-05-16 17:38:36
【问题描述】:

我在 forEach 循环内调用 ajax 请求,但问题是当收到来自 ajax 的响应时,循环已完成(如果我没记错的话)

forEach 循环:

var retrievedContacts = {};
var retrievedContactsArr = [];
contacts.getContacts(function (err, contacts) {
    contacts.forEach(function (entry) {
        if (entry.phoneNumber !== '') {
            retrievedContacts = {
                contact: {
                    "address": {
                        "home": "",
                        "office": ""
                    }
                },
                "profileData": getPhotos(entry.photo, req.token)
            };
            retrievedContactsArr.push(retrievedContacts);
        }
    });
});

函数调用就是上面代码中"profileData": getPhotos(entry.photo, req.token)这一行。

功能:

function getPhotos(url, token){
    var base64Image = '';
    getApiResponse(url+"?access_token="+token,"", function (res1) {
        if (res1.error) {
            console.log('Could not fetch google photos......', res1.error);
        } else {
            base64Image = new Buffer.from(res1.body).toString('base64');
            console.log('base64 is.........................', base64Image);
        }
    });
    return base64Image;
}

Ajax 调用:

function getApiResponse(url, params, next) {
    unirest.get(url)
    .query(params)
    .timeout(60000)
    .end(function (res) {
        if (next)
            next(res);
    });
}

我可以打印响应,但无法将其返回给调用函数。 "profileData" 的值为空字符串。我该如何处理?

【问题讨论】:

  • getContacts() 调用的预期返回值是多少? getApiResponse 是同步的吗?
  • @guest271314 返回值是一个字节数组。我不认为 `getApiResponse' 是同步的。我在某处阅读时没有进行同步,这不是一个好习惯
  • @Satyadev 如果entry.phoneNumber 是一个空字符串,预期的结果是什么?如果getApiResponse 是异步的,你为什么要在getPhotos 调用中立即return base64Image?你认为retrievedContacts.profileData 的值是多少?
  • getApiResponse 返回的值在哪里?你是对的,.forEach() 不等待getPhotos() 返回值。您可以一次执行一个调用,直到没有更多索引可以从 contacts 数组中获取值。

标签: javascript ajax foreach


【解决方案1】:

有两种方法可以解决您的问题。

1。你使 ajax 调用不是异步的

即,使您的 AJAX 调用同步。 在这种方法中,您失去了异步 ajax 调用的好处。

2。更改代码的逻辑。 (推荐!)

所以思路是,什么时候推送你检索到的联系人信息,你只要得到它在数组中的位置,然后把这个位置值传递给获取照片的函数,这样在检索到照片数据后,只需设置它以更正响应检索到的联系信息。

var retrievedContacts = {};
var retrievedContactsArr = [];
contacts.getContacts(function (err, contacts) {
    contacts.forEach(function (entry) {
        if (entry.phoneNumber !== '') {
            retrievedContacts = {
                contact: {
                    "address": {
                        "home": "",
                        "office": ""
                    }
                },
                "profileData": false
            };
            retrievedContactsArr.push(retrievedContacts);
            var retrievedContactsPos = retrievedContactsArr.length - 1;
            getPhotos(entry.photo, req.token, retrievedContactsPos);
        }
    });
});



function getPhotos(url, token, pos){
    var base64Image = '';
    getApiResponse(url+"?access_token="+token,"", [pos, function (res1, pos)      {
        if (res1.error) {
            console.log('Could not fetch google photos......', res1.error);
        } else {
            base64Image = new Buffer.from(res1.body).toString('base64');
            retrievedContactsArr[pos]["profileData"] = base64Image;
        }
    }]);
}

function getApiResponse(url, params, next) {
    unirest.get(url)
    .query(params)
    .timeout(60000)
    .end(function (res) {
        if (next)
            next[1](res, next[0]);
    });
}

如果 retrievedContactsArr 不是全局变量,代码可能会更新如下:

var retrievedContacts = {};
    var retrievedContactsArr = [];
    contacts.getContacts(function (err, contacts) {
        contacts.forEach(function (entry) {
            if (entry.phoneNumber !== '') {
                retrievedContacts = {
                    contact: {
                        "address": {
                            "home": "",
                            "office": ""
                        }
                    },
                    "profileData": false
                };
                retrievedContactsArr.push(retrievedContacts);
                var retrievedContactsPos = retrievedContactsArr.length - 1;
                getPhotos(entry.photo, req.token, retrievedContactsArr, retrievedContactsPos);
            }
        });
    });
    
    
    
    function getPhotos(url, token, retrievedContactsArr, pos){
        var base64Image = '';
        getApiResponse(url+"?access_token="+token,"", [retrievedContactsArr, pos, function (res1, pos)      {
            if (res1.error) {
                console.log('Could not fetch google photos......', res1.error);
            } else {
                base64Image = new Buffer.from(res1.body).toString('base64');
                retrievedContactsArr[pos]["profileData"] = base64Image;
            }
        }]);
    }

    function getApiResponse(url, params, next) {
        unirest.get(url)
        .query(params)
        .timeout(60000)
        .end(function (res) {
            if (next)
                next[2](res, next[0], next[1]);
        });
    }

【讨论】:

  • retrievedContactsArrgetPhotos 函数中不可访问。
  • 为什么retrievedContactsArr 无法访问?不是在全局范围内定义的吗?
  • 是的,它不在全球范围内。我将其更改为:function getPhotos(retrievedContactsArr, url, token, pos) 和这样的函数调用:getPhotos(retrievedContactsArr, entry.photo, req.token, retrievedContactsPos); 但我不确定这是否正确?
  • @Satyadev 我已经更新了我的答案。但是,我说,有什么特殊原因不应该保留retrievedContactsArr 全局变量吗?
  • 错误:Cannot set property 'profileData' of undefined at:retrievedContactsArr[pos]["profileData"] = base64Image;
猜你喜欢
  • 1970-01-01
  • 2020-09-20
  • 2015-11-26
  • 1970-01-01
  • 2016-12-23
  • 1970-01-01
  • 1970-01-01
  • 2020-05-01
相关资源
最近更新 更多