简体   繁体   中英

Javascript Promise.all confusion

I am using Javascript/Typescript in order to format a password value on a collection of PersonModel objects. I am executing a Promise on each element in the Collection.

I am using Promise.all to allow all Promises to complete, and then want to return the formatted collection.

However, I get an error at build time.

PersonService.ts

private decryptPersons(persons: PersonModel[]): Promise<PersonModel[]> {
    return new Promise<PersonModel[]>(resolve => {
        let promises: Array<Promise<string>> = [];
        let decryptedPersons: PersonModel[] = [];
        for (let i: number = 0; i < persons.length; i++) {
            let ciphertext: string = persons[i].password;
            promises.push(this.decrypt(ciphertext).then((password: string) => {  // <== line 357
                persons[i].password = password;
                decryptedPersons.push(persons[i]);
            }));
        }
        Promise.all(promises).then(() => {
            resolve(decryptedPersons);
        });
    });
}

private decrypt(value: string): Promise<string> {
    return new Promise<string>(resolve => {
        this.encrypter.decrypt(value).then((result: string) => {
            resolve(result);
        });
    });
}

Error

 ERROR in ./app/pages/service/personService.ts (357,31): error TS2345: Argument of type 'Promise<void>' is not assignable to parameter of type 'Promise<string>'. Type 'void' is not assignable to type 'string'. 

I am no expert with Javascript, so my structure may me incorrect. If anyone can advise, I would appreciate it.

You're trying to push the following into your promises array:

this.decrypt(ciphertext).then((password: string) => {  // <== line 357
    persons[i].password = password;
    decryptedPersons.push(persons[i]);
})

but your function here doesn't return anything, so this is going to evaluate to a Promise<void> .

You're also abusing the "explicit promise construction antipattern" in several places here.

Give this a try:

private decryptPersons(persons: PersonModel[]): Promise<PersonModel[]> {
    return Promise.all(persons.map(person =>
        this.decrypt(person.password)
            .then(password => {
                person.password = password;
                return person;
            });
    ));
}

private decrypt(value: string): Promise<string> {
    return this.encrypter.decrypt(value);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM