如何在交互式调用中使用承诺?
How to use promises in an interactive call?
我正在检索表单(通过 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()
调用。
我也不能简单地为对话框创建 Promise,因为我必须先创建该 Promise 才能将其传递给 form()
,但我需要 [=12] 返回的 Promise =] 在我创建对话框之前解决。有一种 bootstrap 问题。
这里有什么方法可以使用 promise,还是我应该坚持来回传递回调?
您仍然可以在响应中传递回调。只需将响应和回调数组传递给 resolve
。在 .then
回调中,您可能会破坏数组。简而言之,您可以这样写:response => resolve([response.formFields, **your_callback**])
和 .then(([fields, callback]) ...
。但在我看来,代码很臭,你应该将 from
函数分解为两个独立的函数,以避免来回传递回调
您可以将问题分为三个部分:
form
- 检索表单 - 采用名称和 returns Promise 的函数使用字段解析。
askUser
- 收集输入 - 接受字段、显示表单和 return 提交数据的 Promise 的函数。
submit
- 提交表单 - 获取数据的函数,return 是网络结果的承诺。
你可以将三者组合在一起:
form('example')
.then(askUser)
.then(submit)
.catch(errorHandler)
哪个 return Promise 最终会通过提交操作解决。
form
将其行为包装在回调周围,如果不将 form
拆分为两个函数,就无法真正避免该回调。但是,它完全没问题 - 它被称为 .
您可以这样使用它:
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();
});
});
}
我正在检索表单(通过 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()
调用。
我也不能简单地为对话框创建 Promise,因为我必须先创建该 Promise 才能将其传递给 form()
,但我需要 [=12] 返回的 Promise =] 在我创建对话框之前解决。有一种 bootstrap 问题。
这里有什么方法可以使用 promise,还是我应该坚持来回传递回调?
您仍然可以在响应中传递回调。只需将响应和回调数组传递给 resolve
。在 .then
回调中,您可能会破坏数组。简而言之,您可以这样写:response => resolve([response.formFields, **your_callback**])
和 .then(([fields, callback]) ...
。但在我看来,代码很臭,你应该将 from
函数分解为两个独立的函数,以避免来回传递回调
您可以将问题分为三个部分:
form
- 检索表单 - 采用名称和 returns Promise 的函数使用字段解析。askUser
- 收集输入 - 接受字段、显示表单和 return 提交数据的 Promise 的函数。submit
- 提交表单 - 获取数据的函数,return 是网络结果的承诺。
你可以将三者组合在一起:
form('example')
.then(askUser)
.then(submit)
.catch(errorHandler)
哪个 return Promise 最终会通过提交操作解决。
form
将其行为包装在回调周围,如果不将 form
拆分为两个函数,就无法真正避免该回调。但是,它完全没问题 - 它被称为
您可以这样使用它:
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();
});
});
}