如何在回调中使用 "this"?

How to use "this" inside a callback?

我在下面的代码中 url 的另一端有一个休息服务,returns 是 s3 存储桶中所有对象的名称。我正在尝试创建一个简单的 Alexa 技能,告诉我该桶中有多少对象。我的问题是,在 http get 请求中,术语 "this" 没有引用与在 http get 请求之外的相同的东西。我如何在 get 请求中使用 "this" 或 return 我的 http get 请求中的 "count" 变量?

"use strict";
var Alexa = require("alexa-sdk");
var Client = require('node-rest-client').Client;

exports.handler = function(event, context, callback) {
    var alexa = Alexa.handler(event, context);
    alexa.registerHandlers(handlers);
    alexa.execute();
};

var handlers = {
    'Launch Request': function() {
        this.emit('CountItems');
    },
    'ContentsIntent': function() {
        this.emit('CountItems');
    },
    'CountItems': function() {
        var client = new Client();
        var count = undefined;
        client.get("URL", function (data, response) {
            console.log(data['Keys'].length);
            count = data['Keys'].length;
        });
        this.emit(':tell', 'There are ' + count + ' items in your s3 bucket.');
    }
};

变量 count 应该在闭包内外都可用。 如果你想在 get-closure 范围内使用 this 的外部上下文,你可以这样做:

var that = this;
client.get("URL", function (data, response) {
        console.log(data['Keys'].length);
        count = data['Keys'].length;
        that.emit(':tell', 'There are ' + count + ' items in your s3 bucket.');
});

这取决于您希望 this 值是什么。如果您希望它是 client.get() 调用之前的值,那么通常的方法(ES6 之前)只是将其值保存到 client.get() 之前的局部变量中,然后引用它保存的值而不是 this。此外,唯一可以使用计数的地方是回调内部,因此您也必须将 .emit() 放在那里:

var handlers = {
    'Launch Request': function() {
        this.emit('CountItems');
    },
    'ContentsIntent': function() {
        this.emit('CountItems');
    },
    'CountItems': function() {
        var client = new Client();
        var self = this;
        client.get("URL", function (data, response) {
            let count = data['Keys'].length;  
            self.emit(':tell', 'There are ' + count + ' items in your s3 bucket.');
        });
    }
};

你也可以使用.bind():

var handlers = {
    'Launch Request': function() {
        this.emit('CountItems');
    },
    'ContentsIntent': function() {
        this.emit('CountItems');
    },
    'CountItems': function() {
        var client = new Client();
        client.get("URL", function (data, response) {
            let count = data['Keys'].length;  
            this.emit(':tell', 'There are ' + count + ' items in your s3 bucket.');
        }.bind(this));
    }
};

在 ES6(node.js 的现代版本)中,您可以使用箭头函数定义回调,这将在回调中使用 this 的词法值:

var handlers = {
    'Launch Request': function() {
        this.emit('CountItems');
    },
    'ContentsIntent': function() {
        this.emit('CountItems');
    },
    'CountItems': function() {
        var client = new Client();
        client.get("URL", (data, response) => {
            let count = data['Keys'].length;  
            this.emit(':tell', 'There are ' + count + ' items in your s3 bucket.');
        });
    }
};

在 ES6 环境中,大多数人发现箭头函数是最干净的做事方式。