如何从for循环返回解析的Promise Like对象

时间:2018-10-03 22:53:25

标签: javascript typescript promise

我在自己的函数中有一个类似于promise的对象,该对象使用网络加密API解密给定消息。问题是,在我的解密函数中,我想尝试几个不同的值作为输入,并在for循环中多次运行此对象(如对象)的Promise,最后,函数应返回这些Promise中成功解决的对象。 >

public decryptMessage(latitude: [string, number], longitude: [string, number], ciphertext: string) {
    //get salt 
    const salt = localStorage.getItem("salt")
    const retrievedSaltArray = JSON.parse(salt)
    const saltBytes = new Uint8Array(retrievedSaltArray)

    //get iv
    const iv = localStorage.getItem("iv")
    const retrievedIvArray = JSON.parse(iv)
    const ivBytes = new Uint8Array(retrievedIvArray)

    //get tolerance distance
    let toleranceDistance = parseInt(JSON.parse(localStorage.getItem("toleranceDistance")))

    //get original keyHash
    let originalHash = localStorage.getItem("keyhash")

    //create location inputs(locations with adjacent quadrants)
    let location = new Location(latitude, longitude)
    let locationInputs = location.prepareReceiverLocationInputs()

    let encryptionTool = new EncryptionHelper(saltBytes, ivBytes)

    for (let i = 0; i <= locationInputs.length - 1; i++) {
        let plaintText = encryptionTool.decrypt(locationInputs[i], ciphertext, originalHash)
        plaintText.then(function (plaintTextResult) {
            return plaintTextResult
        })
    }

}

因此,在这里我要尝试做的是,此承诺(如ojbect一样)应为for循环中运行的cryptoTool.decryp(),然后解析的这些承诺中的任何一个都应为cryptoMessage方法的返回值。但是,此encryptionTool.decrypt方法使用webcrypto api,因此它没有拒绝或捕获方法,因为它是一个类似于promise的方法。

1 个答案:

答案 0 :(得分:0)

由于诺言表示将来将可用的值,因此您无法(同步)测试成功的诺言。取而代之的是,您必须使用可用的函数来操纵和组合承诺。我假设encryptionTool.decrypt返回PromiseLike<string>;如果它是其他PromiseLike<T>的{​​{1}},则在下面将T替换为string

首先,您可以使用TPromise.resolve转换为PromiseLike<string>。然后,您想使用Promise<string>来获取一个Promise数组并给您返回结果数组的Promise,因此您可以编写一个Promise.all回调来扫描该数组并获取您想要的结果。一个潜在的问题是,如果提供的Promise中的 any 被拒绝,then就会被拒绝,在这种情况下,您将看不到其他结果。因此,在使用Promise.all之前,需要使用Promise.all来将拒绝映射到哨兵值,例如catch。完整的代码看起来像这样(我没有测试过,所以可能会有错误):

null

请注意,最终的 // Assuming that encryptionTool.decrypt returns a PromiseLike<string>, // promises will be a Promise<string | null>[]. let promises = []; for (let i = 0; i <= locationInputs.length - 1; i++) { promises.push( Promise.resolve(encryptionTool.decrypt(locationInputs[i], ciphertext, originalHash)) .catch((error) => null)); } return Promise.all(promises).then((results) => { // results is a (string | null)[]. // Look through it, find the non-null result and return it. }); 调用会为最终结果生成一个承诺,然后您将此承诺同步返回给then的调用方。

另一种方法是使decryptMessage为异步函数,以便您可以以更熟悉的样式进行编程。将decryptMessage替换为public decryptMessage,然后使用如下代码:

public async decryptMessage

请注意,这种方式是直到上一次解密失败后才开始进行解密,因此该过程可能需要更长的时间才能完成,具体取决于网络加密API的实现方式。

相关问题