简体   繁体   中英

Use `this` object of the class in array map function with async, await - Nodejs, Javascript

I need to use to call this object in the map function. I already followed related answers. But all are showing same exception.

This is my class

const userServiceClient = require("./clients/user-service-client.js");

class GetProfilesByQueryHandler {

    constructor(userRepo) {
        this.userRepo = userRepo;
    }

    /**
     * Returns profiles
     * @param {any} req 
     */
    async handleHttp(req) {
        const users = await userServiceClient.getUserByQuery(query, req.reqId);      

        users.map((user) => {
            user.profile = await this.userRepo.findByReferenceId(user.id);
        });

        console.log(users);
    }

}

module.exports = GetProfilesByQueryHandler;

I have tried following ways and it throwing related exceptions.

users.map((user) => {
    user.profile = await this.userRepo.findByReferenceId(user.id);
});

----------------- Result ------------------------------

user.profile = await this.userRepo.findByReferenceId(user.id);',
     '                                 ^^^^',
     'SyntaxError: Unexpected token this',
######################################################

users.map(function(user) {
        user.profile = await this.userRepo.findByReferenceId(user.id);
}.bind(this));

----------------- Result ------------------------------

user.profile = await this.userRepo.findByReferenceId(user.id);',
    '                                 ^^^^',
'SyntaxError: Unexpected token this'

######################################################

users.map(this._getProfile, {repo: this.userRepo});

_getProfile(user) {
        return user.profile = await this.repo.findByReferenceId(user.id);
}

----------------- Result ------------------------------

'        return user.profile = await this.repo.findByReferenceId(user.id);',
'                                    ^^^^',
'',
'SyntaxError: Unexpected token this',

######################################################
var self = this;

users.map((user) => {
    user.profile = await self.userRepo.findByReferenceId(user.id);
});

----------------- Result ------------------------------

'            user.profile = await self.userRepo.findByReferenceId(user.id);',
'                                 ^^^^',
'',
'SyntaxError: Unexpected identifier',

######################################################
var that = this;

users.map((user) => {
    user.profile = await that.userRepo.findByReferenceId(user.id);
});

----------------- Result ------------------------------

'            user.profile = await that.userRepo.findByReferenceId(user.id);',
'                                 ^^^^',
'',
'SyntaxError: Unexpected identifier

######################################################
var obj = {repo: this.userRepo};

users.map((user) => {
    user.profile = await this.repo.findByReferenceId(user.id);
}, obj);

----------------- Result ------------------------------

'            user.profile = await this.repo.findByReferenceId(user.id);',
'                                 ^^^^',
'',
'SyntaxError: Unexpected token this',

######################################################

What is the way to do this. Lot of questions are related with this. But all answers is not working for me.

EDIT : I added a second snippet, if you want to log and return the real result of your async call. Hope it helps!

You just miss the async keyword in your arrow function:

 const userServiceClient = require("./clients/user-service-client.js"); class GetProfilesByQueryHandler { constructor(userRepo) { this.userRepo = userRepo; } /** * Returns profiles * @param {any} req */ async handleHttp(req) { const users = await userServiceClient.getUserByQuery(query, req.reqId); //I added a "async" here. users.map(async (user) => { user.profile = await this.userRepo.findByReferenceId(user.id); }); //Without this async, your arrow function is not aynchronous //and you can't use await within it. //BTW this console.log won't log users after the map upper. console.log(users); } } module.exports = GetProfilesByQueryHandler; 

I could not test that but it is syntactically correct.

Second possibility to return the finak result :

 const userServiceClient = require("./clients/user-service-client.js"); class GetProfilesByQueryHandler { constructor(userRepo) { this.userRepo = userRepo; } /** * Returns profiles * @param {any} req */ async handleHttp(req) { const users = await userServiceClient.getUserByQuery(query, req.reqId); //I added a "async" here. The promises are now put in a table const tableOfPromises = users.map(async(user) => { user.profile = await this.userRepo.findByReferenceId(user.id); }) //The engine will stop executing the code here untill all your promises return. const finalResult = await Promise.all(tableOfPromises) //All your promises have returned. console.log(users) return finalResult } } module.exports = GetProfilesByQueryHandler; 

Not tested but should work. Try setting the context explicitly

users.map(this._getProfile.call({repo: this.userRepo}));

_getProfile(user) {
        var self = this;
        return function (user) { user.profile = await self.repo.findByReferenceId(user.id); }
}

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