如何使用 Node.js 中的 Promises 对异步调用进行排序?
How to sequence async calls with Promises in Node.js?
我是 Javascript 的新手,无法理解如何一个接一个地制作我的函数 运行。我想用 Promise 来实现这个。
我正在按照 Facebook Messenger 教程制作聊天机器人。基本上就是想一个接一个发消息
如果我调用以下行:
sendTextMessage(recipientID, "1");
sendTextMessage(recipientID, "2");
sendTextMessage(recipientID, "3");
sendTextMessage(recipientID, "4");
sendTextMessage(recipientID, "5");
我想先发送消息“1”。然后是“2”、“3”等等。 (而不是按随机顺序发送,这是这里的问题。)
这里是相关的辅助函数。
function sendTextMessage(recipientId, messageText) {
var messageData = {
recipient: {
id: recipientId
},
message: {
text: messageText
}
};
callSendAPI(messageData);
}
这里是callSendAPI函数。
function callSendAPI(messageData) {
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);
}
} else {
console.error("Failed calling Send API", response.statusCode, response.statusMessage, body.error);
}
});
}
我已经卡了一段时间了。任何帮助将不胜感激。
我试过了,但没用。 =(
sendTextMessage(recipientID, "1")
.then(sendTextMessage(recipientID, "2"))
.then(sendTextMessage(recipientID, "3"));
在您的示例中,没有承诺,这就是它不起作用的原因。
request
软件包不兼容,但您可以安装 request-promise
,它是 request
和 bluebird
的包装器。
假设您正在使用 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);
}
请注意,您必须 return 承诺,否则调用该函数的行无法使用它。
要完成这项工作,请对您的两个辅助函数做出 return 承诺。因此,在 callSendAPI
中,您创建了一个 return,而 sendTextMessage
应该只是 return 它从 callSendAPI
获得的相同承诺。最后,确保将函数传递给 then
调用,而不是 执行 函数。您可以使用 .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');
});
我是 Javascript 的新手,无法理解如何一个接一个地制作我的函数 运行。我想用 Promise 来实现这个。
我正在按照 Facebook Messenger 教程制作聊天机器人。基本上就是想一个接一个发消息
如果我调用以下行:
sendTextMessage(recipientID, "1");
sendTextMessage(recipientID, "2");
sendTextMessage(recipientID, "3");
sendTextMessage(recipientID, "4");
sendTextMessage(recipientID, "5");
我想先发送消息“1”。然后是“2”、“3”等等。 (而不是按随机顺序发送,这是这里的问题。)
这里是相关的辅助函数。
function sendTextMessage(recipientId, messageText) {
var messageData = {
recipient: {
id: recipientId
},
message: {
text: messageText
}
};
callSendAPI(messageData);
}
这里是callSendAPI函数。
function callSendAPI(messageData) {
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);
}
} else {
console.error("Failed calling Send API", response.statusCode, response.statusMessage, body.error);
}
});
}
我已经卡了一段时间了。任何帮助将不胜感激。
我试过了,但没用。 =(
sendTextMessage(recipientID, "1")
.then(sendTextMessage(recipientID, "2"))
.then(sendTextMessage(recipientID, "3"));
在您的示例中,没有承诺,这就是它不起作用的原因。
request
软件包不兼容,但您可以安装 request-promise
,它是 request
和 bluebird
的包装器。
假设您正在使用 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);
}
请注意,您必须 return 承诺,否则调用该函数的行无法使用它。
要完成这项工作,请对您的两个辅助函数做出 return 承诺。因此,在 callSendAPI
中,您创建了一个 return,而 sendTextMessage
应该只是 return 它从 callSendAPI
获得的相同承诺。最后,确保将函数传递给 then
调用,而不是 执行 函数。您可以使用 .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');
});