我正在尝试使用promise来调用函数getTweets。 不是使用AJAX电话,而是一个简单的承诺'电话'从1个javascript文件到另一个。 该功能有效,但我一直未定义'。 我已经在stackoverflow上阅读了几十个问题并花了好几天时间 理解承诺,但仍然无法解决。
var Twit = require('twit') // Imports the Twitter library
require('dotenv').config() // to get the environment vars into the app
// This is the function:
function getTweets (screen_name) {
let T = new Twit({ /* <twitter key and token here> */ });
T.get('statuses/user_timeline', { screen_name: screen_name, count: 3}, function (err, data, response) {
let myTweets = [];
for (let i in data) {
let text = data[i].text;
myTweets.push(text);
}
return myTweets;
})
}
module.exports.getTweets = getTweets;
这是试图获取推文的承诺:
var promise = tweets.getTweets('dizid');
promise.then(
console.log(myTweets),
console.log(err))
// gives error: promise.then(
// ^
// TypeError: Cannot read property 'then' of undefined
非常感谢任何帮助。
答案 0 :(得分:1)
你的问题是你永远不会从getTweets()
函数返回任何内容,即使它需要返回一个承诺。该函数调用T.get()
并向其传递回调函数。您从此回调函数返回但这不会执行任何操作,并不表示此值从getTweets()
返回。
在处理异步调用时,这是一个非常常见的错误。需要做的是让getTweets()
返回一个应该得到解决的承诺
使用未实现promise接口的异步调用时,需要使用新的promise来包装此调用。您的getTweets()
函数应如下所示:
function getTweets (screen_name) {
let T = new Twit({ /* <twitter key and token here> */ });
return new Promise(function(resolve, reject) {
T.get('statuses/user_timeline', { screen_name: screen_name, count: 3}, function (err, data, response) {
if (err) {
reject(err); // Reject the promise since there was an error
} else {
let myTweets = [];
for (let i in data) {
let text = data[i].text;
myTweets.push(text);
}
resolve(myTweets); // Resolve the promise with the result
}
});
});
}
但是,似乎Twit
API 支持支持promise接口,因此您可以使用T.get()
创建的承诺,而不是提供回调函数。 HMR的答案解释了如何做到这一点。
你犯的另一个错误是这段代码:
promise.then(
console.log(myTweets),
console.log(err))
您编写它的方式,它读取“运行console.log(myTweets)
和 console.log(err)
,然后使用结果调用promise.then()
前者作为第一个参数,结果后者作为第二个参数。
then()
将回调函数(根据promise的解析/拒绝而调用)作为参数,因此代码应如下所示:
promise.then(
function(myTweets) {
console.log(myTweets);
},
function(err) {
console.log(err);
});
如果你对进一步的事情感兴趣,使用异步代码的现代方法是async/await
,这是promises的语法糖,它允许你编写更类似于常规同步代码的异步代码。
标记为async
的函数将隐式返回一个promise,但是您将其写为就像返回常规值一样。在await
函数内使用async
关键字将隐式等待承诺解析和解包已解析的值。这样做的主要实际好处是,您可以在循环中使用异步调用,并使用常规try-catch块处理错误。您的getTweets()
函数使用async/await
:
async function getTweets(screen_name) {
let T = new Twit({ /* <twitter key and token here> */ });
const data = await T.get('statuses/user_timeline', { screen_name: screen_name, count: 3});
// Let's also use map() instead of a for loop
let myTweets = data.map(function(item) { return item.text; });
return myTweets;
}
答案 1 :(得分:0)
由于get似乎返回promise,因此您不需要使用回调。获取推文看起来像这样:
// in getTweets
return T.get(
'statuses/user_timeline',
{ screen_name: screen_name, count: 3}
).then(
function (data) {
console.log("data:",JSON.stringify(data,undefined,2));
return data.map(item=>item.text);
}
)
// exports the function getTweets so that other modules can use it
module.exports.getTweets = getTweets;
如果这不起作用,请告诉我们该程序的输出是什么(更新问题)。
您可以像这样调用getTweets:
tweets.getTweets('dizid')
.then(
myTweets=>
console.log(myTweets),
err=>
console.log(err)
)
答案 2 :(得分:-1)
我认为你忘了添加功能,如
promise.then(function(res){
//code
}
答案 3 :(得分:-2)
你的.then()应该包含一个回调函数。
promise.then( res => {
console.log(res);
});
编辑:我使用ES6语法进行箭头功能,以防您对此有所了解。