[英]Javascript: add function as parameter to predefined callback function
[英]Add an extra parameter to a callback function in Javascript
您好 Stackoverflow 用户,
许多像我这样的人都在搜索如何将额外的参数传递给回调函数。 这些问题的标题相似,但实际上它们具有不同的挑战和许多解决方法。 另外,分享实践以增加经验总是很高兴。
最近,我在我的 node js 项目中遇到了一个非常简单的挑战。 我与之通信的其中一个 API 有一个同步工作的 SDK。 而且我曾经每次都传递回调函数(当您有相互依赖的请求并且需要在应用程序层内传输一些数据时,这很烦人)。
想象一下这样的计划支付流程,客户端向服务器发送一个请求,其中包括所选计划和他的 ID。 服务器 API 层收到请求数据后,会将其传递给第三方服务函数( .create(...)
)。 第三方服务函数接收带有 2 个参数function(err, plan_document)
的回调。 然后,回调应该通过请求中的 ID 将选定的计划逻辑应用于客户端。
** 我们需要将客户端和计划的数据传递给回调函数以应用逻辑。 第三方服务为回调提供了一个 plan_document 参数,我们仍然需要以某种方式将客户端 ID 从 API 层传递给服务。
代码将如下所示。
const create_plan_agreement = (req, res) => {
// some code
var client_id = req.auth.client_id;
third_party.plan_agreement.create({}, update_plan_agreement);
};
const update_plan_agreement = (err, plan_document, client_id) => {
/*
The third-party `third_party.plan_agreement.create` function passes the first
two parameters and somehow we need to add the client_id
*/
console.log('client plan activated');
active_client_plan(plan_document, client_id);
};
- - - - - - - - - 编辑 - - - - - - - - -
我想知道如果流程更长并且我需要客户端 ID 比这样的更新功能更远怎么办。
const create_plan_agreement = (req, res) => {
// some code
var client_id = req.auth.client_id;
third_party.plan_agreement.create({}, update_plan_agreement);
};
const update_plan_agreement = (err, plan_document) => {
console.log('plan activated, send notification to the client');
third_party.plan_agreement.update(plan_document, send_agreement_notification);
};
const send_agreement_notification = (err, plan_document) => {
console.log('client plan activated');
active_client_plan(plan_document, this.client_id);
};
在这种情况下我该怎么办? 我是否应该一直重复.bind({'client_id': client_id})
函数,直到流程的最后一步?
如果您想支持老年人,您可以使用包含回调轻松绑定,如下所示:
const create_plan_agreement = (req, res) => { // some code var client_id = req.auth.client_id; third_party.plan_agreement.create({}, function(params, from, create) { update_plan_agreement(params, from, create, client_id) }); }; const update_plan_agreement = (err, plan_document, client_id) => { /* The third-party `third_party.plan_agreement.create` function passes the first two parameters and somehow we need to add the client_id */ console.log('client plan activated'); active_client_plan(plan_document, client_id); };
传统的方法是使用闭包。 在父范围内定义函数,以便它们可以将client_id
作为封闭变量(有点像全局变量)访问:
const create_plan_agreement = (req, res) => {
// some code
var client_id = req.auth.client_id;
const update_plan_agreement = (err, plan_document) => {
console.log('plan activated, send notification to the client');
third_party.plan_agreement.update(plan_document, send_agreement_notification);
};
const send_agreement_notification = (err, plan_document) => {
console.log('client plan activated');
// Note: this function can access client_id
// because it is in scope
active_client_plan(plan_document, client_id);
};
third_party.plan_agreement.create({}, update_plan_agreement);
};
闭包之于作用域就像对象之于类。 闭包是作用域的一个实例。 因此,与常规全局变量不同,每次调用create_plan_agreement()
都会使用自己的client_id
副本创建自己的闭包。
使用现代 javascript,通常使用Promise
更容易处理这个问题。 转换遗留函数以返回Promise
,然后您可以使用async/await
:
const create_plan_agreement = async (req, res) => {
// some code
var client_id = req.auth.client_id;
try {
var plan_document = await plan_agreement_create({});
var updated_plan_document = await update_plan_agreement(plan_document);
send_agreement_notification(updated_plan_document, client_id);
}
catch (err) {
// handle errors here.
}
};
const plan_agreement_create = (arg) {
return new Promise ((ok, fail) => {
third_party.plan_agreement.create({}, (err, result) => {
if (err) {
return fail(err);
}
ok(result);
});
})
}
const update_plan_agreement = (plan_document) => {
return new Promise ((ok, fail) => {
third_party.plan_agreement.update(plan_document, (err, result) => {
if (err) return fail(err);
ok(result);
});
});
};
const send_agreement_notification = (plan_document, client_id) => {
active_client_plan(plan_document, client_id);
};
或者即使没有async/await
Promise
仍然使回调更易于使用:
const create_plan_agreement = async (req, res) => {
// some code
var client_id = req.auth.client_id;
plan_agreement_create({})
.then(doc => update_plan_agreement(doc));
.then(doc => {
send_agreement_notification(doc, client_id)
})
.catch(err => {
// handle errors here.
});
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.