Javascript 在for循环解析后未定义数组
我有一个未定义数组的问题,它在for循环中被填充后得到解决。如下所示:Javascript 在for循环解析后未定义数组,javascript,arrays,node.js,Javascript,Arrays,Node.js,我有一个未定义数组的问题,它在for循环中被填充后得到解决。如下所示: function mainFunction() { getUnreadMails().then(function(mailArray) { // Do stuff with the mailArray // Here it is undefined }) } function getUnreadMails() { var mailArray = []; ret
function mainFunction() {
getUnreadMails().then(function(mailArray) {
// Do stuff with the mailArray
// Here it is undefined
})
}
function getUnreadMails() {
var mailArray = [];
return new Promise(function(resolve, reject) {
listMessages(oauth2Client).then(
(messageIDs) => {
for(var i = 0; i < messageIDs.length; i++) {
getMessage(oauth2Client, 'me', messageIDs[i]).then(function(r) {
// Array gets filled
mailArray.push(r);
}, function(error) {
reject(error);
})
}
// Array gets resolved
resolve(mailArray);
},
(error) => {
reject(error);
}
)
});
}
function main函数(){
getUnreadMails().then(函数(mailArray){
//处理邮件数组
//这里没有定义
})
}
函数getUnreadMails(){
var mailArray=[];
返回新承诺(功能(解决、拒绝){
listMessages(oauth2Client)。然后(
(messageid)=>{
for(var i=0;i{
拒绝(错误);
}
)
});
}
listMessages()
和getmessages()
都返回一个承诺,因此它被链接在这里。你知道我为什么会得到一个未定义的邮件数组吗?我的猜测是,当它得到解决时,它还没有被填满。其次,我认为这个流程不是一个好的实践
getMessage(oauth2Client, 'me', messageIDs[i]).then(function(r) {
// Array gets filled
mailArray.push(r);
}, function(error) {
reject(error);
})
是一个异步调用
resolve(mailArray);
不会等待它推送数据,并且会先解析阵列
要解决这个问题,你应该使用Promise.all()
function main函数(){
getUnreadMails().then(函数(mailArray){
//处理邮件数组
//这里没有定义
})
}
函数getUnreadMails(){
var mailArray=[];
返回列表消息(oauth2Client)。然后(
(messageid)=>{
for(var i=0;i{
拒绝(错误);
}
)
}
是一个异步调用
resolve(mailArray);
不会等待它推送数据,并且会先解析阵列
要解决这个问题,你应该使用Promise.all()
function main函数(){
getUnreadMails().then(函数(mailArray){
//处理邮件数组
//这里没有定义
})
}
函数getUnreadMails(){
var mailArray=[];
返回列表消息(oauth2Client)。然后(
(messageid)=>{
for(var i=0;i{
拒绝(错误);
}
)
}
我只是想了解一下marvel308的答案,我认为您需要创建一个新的承诺
,当您的其他人做出承诺时,该承诺就会得到解决。我还没有机会测试这个,但我认为应该可以
function getUnreadMails() {
var mailArray = [];
return new Promise(function(resolve, reject) {
listMessages(oauth2Client).then(
(messageIDs) => {
var messages = [];
for(var i = 0; i < messageIDs.length; i++) {
messages.push(
getMessage(oauth2Client, 'me', messageIDs[i]).catch(reject)
);
}
Promise.all(messages).then(resolve);
},
(error) => {
reject(error);
}
)
});
}
函数getUnreadMails(){
var mailArray=[];
返回新承诺(功能(解决、拒绝){
listMessages(oauth2Client)。然后(
(messageid)=>{
var消息=[];
for(var i=0;i{
拒绝(错误);
}
)
});
}
这样,当所有的
消息
都已解决时,就会调用您第一个承诺的解决
,我想您需要创建一个新的承诺
,当其他承诺解决时,该承诺会得到解决。我还没有机会测试这个,但我认为应该可以
function getUnreadMails() {
var mailArray = [];
return new Promise(function(resolve, reject) {
listMessages(oauth2Client).then(
(messageIDs) => {
var messages = [];
for(var i = 0; i < messageIDs.length; i++) {
messages.push(
getMessage(oauth2Client, 'me', messageIDs[i]).catch(reject)
);
}
Promise.all(messages).then(resolve);
},
(error) => {
reject(error);
}
)
});
}
函数getUnreadMails(){
var mailArray=[];
返回新承诺(功能(解决、拒绝){
listMessages(oauth2Client)。然后(
(messageid)=>{
var消息=[];
for(var i=0;i这样,当所有
消息
都已解析时,就会调用第一个承诺的解析
,因为数组从未定义,所以数组可能是未定义的
;至少在你的代码中没有。在循环中的任何迭代能够解决之前,您的承诺就已经解决了,或者更好地说,抛出(尝试将推到未定义)
除此之外。通过使用Array#map
和Promise.all
,您可以大大简化代码
捕捉一个错误,只是为了重现同样的错误,而不做任何其他事情,这是没有意义的
function getUnreadMails() {
//put this on a seperate line for readability
//converts a single messageId into a Promise of the result
const id2message = id => getMessage(oauth2Client, 'me', id);
return listMessages(oauth2Client)
//converts the resolved messageId into an Array of Promises
.then(messageIDs => messageIDs.map( id2message ))
//converts the Array of Promises into an Promise of an Array
//.then(Promise.all.bind(Promise));
.then(promises => Promise.all(promises));
//returns a Promise that resolves to that Array of values
}
或简称:
function getUnreadMails() {
return listMessages(oauth2Client)
.then(messageIDs => Promise.all(messageIDs.map( id => getMessage(oauth2Client, 'me', id) )))
}
.那么(保证,一切)就行不通了
我希望通过将中间结果划分为不同的步骤/函数,使其更加清晰。但是我打字太快了,没有检查。修正了密码
在简短的版本中,mailArray实际上在哪里填充/解析
Promise.all()
接受承诺数组并返回解析值(或第一次拒绝)的单个承诺
messageIDs.map(…)
返回一个数组和周围的承诺。all()将其“转换”为解析值的单个承诺。
由于我们在承诺链中返回这个承诺,所以返回的承诺(listMessages(oauth2Client)。然后(…)
)也会解析为这个Arra
function mainFunction() {
getUnreadMails().then(function(mailArray) {
// Do stuff with the mailArray
// Here it is undefined
})
}
function getUnreadMails() {
return new Promise(function(resolve, reject) {
listMessages(oauth2Client).then(
(messageIDs) => {
return Promise.all(messageIDs.map(id => getMessage(oauth2Client, 'me', id)))
})
.then((messages) => resolve(messages))
.catch(error => reject(error))
});
}