2017-04-15 36 views
-3

我在下面的代码中的URL的另一端有一个休息服务,它返回s3存储桶中所有对象的名称。我试图创建一个简单的Alexa技能,告诉我该桶中有多少个对象。我的问题是,在http获取请求中,术语“this”没有引用与http获取请求外部相同的内容。如何在get请求中使用“this”或从我的http get请求中返回“count”变量?如何在回调中使用“this”?

"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.'); 
    } 
}; 
+1

的可能的复制[如何访问正确的\'这\'回调里面?](http://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a -callback) – Pineda

回答

1

这取决于你想要的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环境中,大多数人认为箭头功能是最干净的做事方式。

+0

对于非ES6,绑定也是一个optiion:功能(数据,响应){...} .bind(本) – Sasang

+0

@ChrisBell - 是不是有想成为你的客户端''一个参数err' .get()'回调? – jfriend00

+0

@Sasang - 我也添加了这个选项。 – jfriend00

0

可变计数应该可用内部和封闭件的外部。 如果你想使用的这个一开始关闭范围内的外情况下,你可以这样做:

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.'); 
}); 
相关问题