2016-04-18 5 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(), которое нужно решить, прежде чем я смогу создать диалог. Там есть проблема с загрузкой.

Есть ли способ использовать обещания здесь, или я должен придерживаться передающих обратных вызовов назад и вперед?

ответ

2

Вы можете разбить проблему на три части:

  1. form - Получить форму - функция, которая принимает имя и возвращает обещание, разрешенное с помощью полей.
  2. askUser - Сбор данных - функция, которая принимает поля, отображает форму и возвращает обещание с предоставленными данными.
  3. submit - Отправить форму - функция, которая берет данные и возвращает результат сети Promise.

Вы можете чем составляют три вместе:

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

Что бы вернуть обещание в конце концов решить с операцией представить.

1

Вы все равно можете пройти обратный вызов по ответу. Просто передайте массив ответа и обратного вызова на resolve. И в пределах .then callback вы можете уничтожить массив. Короче вы можете написать что-то вроде: 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(); 
    }); 
    }); 
} 
Смежные вопросы