Javascript 如何在Node.js中使用承诺对异步调用排序?
我是Javascript新手,很难理解如何让我的函数一个接一个地运行。我想用承诺来实现这一点 我正在按照Facebook Messenger教程制作聊天机器人。基本上,我想一个接一个地发送消息 如果我拨打以下电话:Javascript 如何在Node.js中使用承诺对异步调用排序?,javascript,node.js,promise,facebook-messenger,Javascript,Node.js,Promise,Facebook Messenger,我是Javascript新手,很难理解如何让我的函数一个接一个地运行。我想用承诺来实现这一点 我正在按照Facebook Messenger教程制作聊天机器人。基本上,我想一个接一个地发送消息 如果我拨打以下电话: sendTextMessage(recipientID, "1"); sendTextMessage(recipientID, "2"); sendTextMessage(recipientID, "3"); sendTextMessage(recipientID, "4"); se
sendTextMessage(recipientID, "1");
sendTextMessage(recipientID, "2");
sendTextMessage(recipientID, "3");
sendTextMessage(recipientID, "4");
sendTextMessage(recipientID, "5");
我希望先发送消息“1”。然后,“2”,“3”等等。(而不是以随机顺序发送,这是这里的问题。)
下面是相关的助手函数
函数sendTextMessage(recipientId,messageText){
var messageData={
收件人:{
id:recipientId
},
信息:{
text:messageText
}
};
callSendAPI(messageData);
}
下面是callSendAPI函数
函数callSendAPI(messageData){
请求({
uri:'https://graph.facebook.com/v2.6/me/messages',
qs:{access_token:PAGE_access_token},
方法:“POST”,
json:messageData
},函数(错误、响应、正文){
如果(!error&&response.statusCode==200){
var recipientId=body.recipientId\u id;
var messageId=body.message\u id;
if(messageId){
console.log(“已成功将id为%s的邮件发送给收件人%s”,
messageId,recipientId);
}否则{
console.log(“已成功调用收件人%s的发送API”,
接受者ID);
}
}否则{
console.error(“调用发送API失败”,response.statusCode,response.statusMessage,body.error);
}
});
}
我被困了一段时间了。任何帮助都将不胜感激 我试过了,但没用=(
在你的例子中,没有承诺,这就是它不起作用的原因。
request
程序包与promise不兼容,但您可以安装request promise
,它是请求
与蓝鸟
的包装
假设您使用的是请求承诺
示例如下所示:
function callSendAPI(messageData) {
// return the promise so you can use the promise where you call the function
return request({
uri: 'https://graph.facebook.com/v2.6/me/messages',
qs: { access_token: PAGE_ACCESS_TOKEN },
method: 'POST',
json: messageData
}).then( function(body) {
var recipientId = body.recipient_id;
var messageId = body.message_id;
if (messageId) {
console.log("Successfully sent message with id %s to recipient %s",
messageId, recipientId);
} else {
console.log("Successfully called Send API for recipient %s",
recipientId);
}
}).catch(function(error) {
console.error("Failed calling Send API", response.statusCode, response.statusMessage, body.error);
});
}
对于其他功能:
function sendTextMessage(recipientId, messageText) {
var messageData = {
recipient: {
id: recipientId
},
message: {
text: messageText
}
};
return callSendAPI(messageData);
}
请注意,您必须返回承诺,否则调用函数的行将无法使用它。在您的示例中,没有承诺,这就是它不起作用的原因。
request
程序包与promise不兼容,但您可以安装request promise
,它是请求
与蓝鸟
的包装
假设您使用的是请求承诺
示例如下所示:
function callSendAPI(messageData) {
// return the promise so you can use the promise where you call the function
return request({
uri: 'https://graph.facebook.com/v2.6/me/messages',
qs: { access_token: PAGE_ACCESS_TOKEN },
method: 'POST',
json: messageData
}).then( function(body) {
var recipientId = body.recipient_id;
var messageId = body.message_id;
if (messageId) {
console.log("Successfully sent message with id %s to recipient %s",
messageId, recipientId);
} else {
console.log("Successfully called Send API for recipient %s",
recipientId);
}
}).catch(function(error) {
console.error("Failed calling Send API", response.statusCode, response.statusMessage, body.error);
});
}
对于其他功能:
function sendTextMessage(recipientId, messageText) {
var messageData = {
recipient: {
id: recipientId
},
message: {
text: messageText
}
};
return callSendAPI(messageData);
}
请注意,您必须返回承诺,否则调用函数的行将无法使用它。要使这项工作正常,请让您的两个助手函数返回承诺。因此,在
callSendAPI
中,您创建并返回一个承诺,sendTextMessage
应该返回它从callSendAPI
获得的相同承诺最后,确保先将函数传递给调用,然后
调用,而不是执行函数。您可以使用.bind()
从现有函数创建新函数,并指定调用时应传递的参数
function callSendAPI(messageData) {
return new Promise(function (resolve, reject) { // ***
request({
uri: 'https://graph.facebook.com/v2.6/me/messages',
qs: { access_token: PAGE_ACCESS_TOKEN },
method: 'POST',
json: messageData
}, function (error, response, body) {
if (!error && response.statusCode == 200) {
var recipientId = body.recipient_id;
var messageId = body.message_id;
if (messageId) {
console.log("Successfully sent message with id %s to recipient %s",
messageId, recipientId);
} else {
console.log("Successfully called Send API for recipient %s",
recipientId);
}
resolve(body); // ***
} else {
console.error("Failed calling Send API", response.statusCode,
response.statusMessage, body.error);
reject(body.error); // ***
}
});
});
}
function sendTextMessage(recipientId, messageText) {
var messageData = {
recipient: {
id: recipientId
},
message: {
text: messageText
}
};
return callSendAPI(messageData); // *** returns promise
}
sendTextMessage(recipientID, "1")
.then(sendTextMessage.bind(null, recipientID, "2")) // *** pass a function reference
.then(sendTextMessage.bind(null, recipientID, "3"))
.catch(function (body) {
console.log('aborted');
});
要实现这一点,请让您的两个助手函数返回承诺。因此,在
callSendAPI
中,您可以创建并返回一个,而sendTextMessage
应该只返回它从callSendAPI
中得到的承诺。最后,确保将函数传递给调用,而不是执行函数。您可以se.bind()
从现有函数创建新函数,并指定调用时应传递的参数
function callSendAPI(messageData) {
return new Promise(function (resolve, reject) { // ***
request({
uri: 'https://graph.facebook.com/v2.6/me/messages',
qs: { access_token: PAGE_ACCESS_TOKEN },
method: 'POST',
json: messageData
}, function (error, response, body) {
if (!error && response.statusCode == 200) {
var recipientId = body.recipient_id;
var messageId = body.message_id;
if (messageId) {
console.log("Successfully sent message with id %s to recipient %s",
messageId, recipientId);
} else {
console.log("Successfully called Send API for recipient %s",
recipientId);
}
resolve(body); // ***
} else {
console.error("Failed calling Send API", response.statusCode,
response.statusMessage, body.error);
reject(body.error); // ***
}
});
});
}
function sendTextMessage(recipientId, messageText) {
var messageData = {
recipient: {
id: recipientId
},
message: {
text: messageText
}
};
return callSendAPI(messageData); // *** returns promise
}
sendTextMessage(recipientID, "1")
.then(sendTextMessage.bind(null, recipientID, "2")) // *** pass a function reference
.then(sendTextMessage.bind(null, recipientID, "3"))
.catch(function (body) {
console.log('aborted');
});