Javascript 使用单个API调用在数组中存储消息列表

Javascript 使用单个API调用在数组中存储消息列表,javascript,node.js,Javascript,Node.js,因此,本质上我有一个函数,该函数进行API调用,获取消息ID列表,如下所示: function getMessageList(auth) { api.users.messages.list({ auth: auth, userId: 'me', }, function(err, response) { if (err) { console.log('The API returned an error: ' +

因此,本质上我有一个函数,该函数进行API调用,获取消息ID列表,如下所示:

function getMessageList(auth) {
    api.users.messages.list({
        auth: auth,
        userId: 'me',
    }, function(err, response) {
        if (err) {
            console.log('The API returned an error: ' + err);
            return;
        }

        var messages = response.messages;

        if (messages.length == 0) {
            console.log('No messages found.');
        } else {
            console.log('messages:');

            var messageList = [];
            for (var i = 0; i < messages.length; i++) {
                var message = messages[i].id;
                getMessage(auth, message, function(response) {
                    messageList.push(response);
                    console.log(messageList);
                });
            }
        }

    });
}
function getMessage(auth, messageId, callback) {
    api.users.messages.get({
        auth: auth,
        userId: 'me',
        id: messageId
    }, function(err, response) {
        if(err) {console.log(err); }
        callback(response);
    });
}
基本上,我希望能够创建一个消息数组,这是我在使用回调函数时所做的,但也希望能够在回调函数之外使用它。可能有点傻,但我对我的JS有点生疏了

我曾想过将该循环放在一个单独的函数(generateMessageList())中,并使用then()承诺,但我无法让它工作。。。也许我的语法错了。下面是它的样子:

function generateMessageList(auth, messages) {
    var messageList = [];
    for (var i = 0; i < messages.length; i++) {
        var message = messages[i].id;
        getMessage(auth, message, function(response) {
            messageList.push(response);
        });
    }
    return messageList;
}
函数generateMessageList(身份验证、消息){
var messageList=[];
对于(var i=0;i
我会尝试
generateMessageList(auth,messages),然后(console.log(messageList))无效


不确定正确的方法是什么,请提供任何指导。

您正在循环中执行异步api调用,循环完成后结果将在那里,messageList将为空。我建议您将注意力放在承诺或观察上,使用它们,您可以轻松地等待所有api调用完成,并将结果映射到数组中


请注意:为什么要对每个消息id执行一个api调用,只需对所有消息id执行一个api调用,并让api返回一个消息数组。

您的代码本质上是异步的。bluebird就是一个很好的例子。所以基本上用承诺包装,然后每个承诺都会从请求的catch块中的成功或错误返回一个对象。有什么意义吗

var Promise = require('bluebird');

function generateMessageList(auth, messages) {
function getMessage(auth, messageId) {
return new Promise(function(resolve,reject){
    api.users.messages.get({
    auth: auth,
    userId: 'me',
    id: messageId
}, function(err, response) {
    if(err) {reject(err);}
    resolve(response);
});
});

}
然后在您的
generateMessageList(auth,messages)

函数generateMessageList(身份验证、消息){
var messageList=[];
返回新承诺(功能(解决、拒绝){
对于(var i=0;i
}

然后,无论您在何处调用
generateMessageList(auth,messages)


只需调用,然后用消息列表捕获返回的承诺。

您的代码目前存在很多竞争条件,并且非常容易出错。但建议是,请删除循环,单独获取ID没有意义,只需对所有消息ID执行一次api调用,让api返回一个消息数组即可。这样就不会有竞争条件,因为它将只处理一个数组。谢谢,我将在几分钟内对此进行测试,不幸的是,API似乎只支持以这种方式获取消息内容(Gmail API)。。。我同意你的看法,以这种方式获取所有内容会更有意义。你编写的generateMessageList()函数中存在一个问题:解析(messageList)不依赖于承诺的完整性。。。所以我不得不做一些修改,让它工作,但我设法找到了它。我添加了我用来让它工作的解决方案。(我没有使用蓝鸟…只是本地js)谢谢,我会调查承诺和可观察到的。这正是我想做的。。。等待api调用完成,只是不确定如何完成。API似乎只支持这种方式。。。我更愿意只收到所有的信息。(Gmail API供参考)
function generateMessageList(auth, messages) {
var messageList = [];
return new Promise(function(resolve,reject){
for (var i = 0; i < messages.length; i++) {
    var message = messages[i].id;
    var promise = getMessage(auth, message);
promise.then(function(result){   messageList.push(result);}).catch(function(err){reject(err);});
}
resolve(messageList);

 });