[英]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.