2016-04-18 53 views
0

我正在檢索表單(通過XMPP,XEP-0004),爲它創建交互式表單對話框,然後在對話框關閉時提交表單。如何在互動電話中使用承諾?

碼(粗略近似爲簡單起見):

function form(name, callback) { 
    server.getForm(name, function(response) { 
    callback(response.formFields, function (data) { 
     server.submitForm(name, data); 
    }); 
    }); 
} 

function main() { 
    form('example', function(fields, callback) { 
    var dialog = ui.formDialog(fields); 
    dialog.addButton('submit', function(data) { 
     callback(data); 
    }); 
    dialog.show(); 
    }); 
} 

注意如何主叫用戶和被叫方交換回調 - 在一個方向上,用於從所述服務器檢索到的字段;另一方面是用戶提交的數據。

我最近發現了JS Promises,我想知道他們是否可以更優雅地替換回調。

我得到儘可能:

function form(name) { 
    return new Promise((resolve, reject) => { 
    server.getForm(
     name, 
     (response) => { resolve(response.formFields) }, 
     reject 
    ); 
    }); 
} 

function main() { 
    form('example').then((fields) => { 
    var dialog = ui.formDialog(fields); 
    dialog.addButton('submit', /* ... */); 
    }); 
} 

但現在我卡住了,因爲我沒有辦法通過提交按鈕的事件回form()電話。

我不能簡單地爲對話創建一個承諾,因爲我必須先創建承諾才能將其傳遞給form(),但我需要在創建之前先解決form()返回的承諾對話框。有一種引導問題。

有沒有某種方法可以在這裏使用promise,或者我應該堅持傳遞迴調嗎?

回答

2

你可以把問題分解成三個部分:

  1. form - 檢索的形式 - 函數需要名稱並返回Promise與字段解決。
  2. askUser - 收集輸入 - 獲取字段的函數,顯示錶單並返回Promise與提交的數據。
  3. submit - 提交表單 - 獲取數據並返回網絡結果的承諾的函數。

可以比組成三個人在一起:

form('example') 
    .then(askUser) 
    .then(submit) 
    .catch(errorHandler) 

這將返回一個承諾與提交操作最終解決。

1

您仍然可以沿響應傳遞迴調。只需將響應數組和回調傳遞給resolve即可。在.then回調中,您可能會破壞陣列。總之,你可以寫如下:response => resolve([response.formFields, **your_callback**]).then(([fields, callback]) ...。但在我看來代碼是臭的,你應該分解from功能分爲兩個獨立的功能,以避免將回調來回

1

form圍繞回調包裝它的行爲,你不能真正避免該回調而不分裂form兩個函數。但是,它是完全正常的 - 它被稱爲disposer pattern

你會使用這樣的:

function form(name, callback) { 
    return server.getForm(name).then(function(response) { 
    return callback(response.formFields); 
    }).then(function (data) { 
    return server.submitForm(name, data); 
    }).catch(function(e) { 
    console.error(e); // or display it in the form, or whatever 
    }); 
} 

function main() { 
    return form('example', function(fields) { 
    return new Promise(function(resolve, reject) { 
     var dialog = ui.formDialog(fields); 
     dialog.addButton('submit', resolve); 
     dialog.show(); 
    }); 
    }); 
}