将元素添加到for循环中的数组中,循环后为空数组

Adding elements to array in a for loop, empty array after loop

本文关键字:数组 循环 元素 for 添加      更新时间:2023-09-26

所以我遇到了以下问题:我有一个数组,其中包含用于加密字符串的密钥。for循环遍历数组,用当前密钥加密字符串,然后将加密的字符串推入新数组。这里的代码:

var enc_gmessages = ['start'];
for(i = 0; i < pubkeys.length; i++) {
    var pubkey = pubkeys[i];
    if(pubkey != 'no' && pubkey != null) {
        var publicKey = openpgp.key.readArmored(pubkey);
        openpgp.encryptMessage(publicKey.keys, content).then(function(pgp_gmessage) {
            //string encrypted successfully
            console.log(pgp_gmessage);
            enc_gmessages.push(pgp_gmessage);
        }).catch(function(error) {
            console.log('error');
        });
    }
}
alert(enc_gmessages);

如果存在有效的公钥,则字符串将成功加密(并记录在控制台中),而数组仅包含for循环之后的"start"元素。有人能指出我做错了什么吗?

您试图在异步操作完成之前从中获取值。

这是不可能的,所以你应该创建一个新的Promise,它的最终结果将是预期的消息数组:

function getMessages(pubkeys) {
    // get an array of Promises for each valid key - each element is 
    // a promise that will be "resolved" with the encrypted message
    var promises = pubkeys.filter(function(pubkey) {
        return pubkey != null && pubkey != 'no';
    }).map(function(pubkey) {
        var publicKey = openpgp.key.readArmored(pubkey);
        return openpgp.encryptMessage(publicKey.keys, content);
    });
    // then once all are resolved, return a new promise that
    // is resolved with the desired array
    return Promise.all(promises).then(function(messages) {
        return ['start'].concat(messages);
    });
}

尽管您可以在Promise.all行之后.catch,但更常见的做法是在调用该行时捕获任何失败。

如果返回数组中的"start"元素只是用于调试,而实际上不是必需的,那么只需将整个返回块替换为return Promise.all(promises)即可。

我认为promise系统在这里造成了麻烦。在openpgp.encryptMessage(...)返回的每个promise的回调中,您将元素推入数组,因此循环在任何操作实际发生之前结束。