2016-11-22 2 views
1

У меня есть мелкое понимание JavaScript Promise и цепочки обещаний. Скажите, у меня есть метод, как показано ниже. Это написано в машинописном, но может быть изменено, чтобы соответствовать JavaScript ES6Возврат обещания от функции

private InsertPersonInDB(p : Person) {  
    return this.db.find({        //<- would this return? 
       selector: {objType: 'Person'}, 
       fields: ['_id'], 
       sort: ['_id'] 
      }).then(result => {       
       let allpersondIds : string[] = []; 
       (result.docs).forEach(rec => { 
        allpersondIds.push(rec._id); 
       }); 
       return allpersondIds;     
      }).then (allpersonIdsInDB => {     
       var id = this.getIdfromPersonName(person.personName, allpersonIdsInDB); 
       person._id = id; 
       return this.db.post(person)   //<- or would this return? 
      } 
} 

//Calling function 
for(let person of this.persons) { 
    InsertPersonInDB(person).then(result => { 
     console.log(result) 
     //Some UI updates  
    }).catch(err => { 
     console.log(err) 
     //Some UI updates notifying user about failure 
    }); 
} 

Вот, у меня есть два возвращения, первым является

возвращения this.db.find

который найти Функция является обещанием

и конец цепи затем возвращается

возвращение this.db.post (человек)

даже пост функция является обещание.

Вот, у меня есть три вопроса

1) Когда эта функция выполняется, что бы вернуться?

2) Если функция немедленно возвращает обещание, когда цепочка thens выполнить?

2) Каковы лучшие подходы к рефакторингу цепочки обещаний в многоуровневом приложении. Например. Несколько цепочек , то необходимо выполнить в сервисе, другие должны быть выполнены в пользовательском интерфейсе, как я могу структурировать свой код обещаний?

ответ

3

Прежде всего, я думаю, вы можете легко проверить наши вопросы, просто сделав несколько небольших примеров для себя. Когда я не понимаю, как это работает, мне очень полезно создать небольшой пример, чтобы просто попробовать и посмотреть, что произойдет. Давайте делать что для этого вопроса, а также (см также https://plnkr.co/edit/K18o4Lp2jtUincjyG5wi?p=preview для рабочей версии, откройте консоль, чтобы увидеть результаты!):

function test() { 
    return returnPromise().then((value) => { 
    console.log('1st then, inside test(): ' + value); 
    return 'Hello'; 
    }).then((value) => { 
    console.log('2nd then, inside test(): ' + value); 
    return 'world'; 
    }); 
} 

function returnPromise() { 
    return new Promise(function(resolve, reject) { 
    resolve('start of new Promise'); 
    }); 
} 

test().then((value) => { 
    console.log('3rd then, after calling test: ' + value); 
}); 

Для ваших вопросов:

  1. Вы возвращаетесь обещание вместе с все связанные функции then. Если вы добавите еще then к возвращенному обещанию, он будет добавлен в конце цепи. Это то, что вы видите, когда делаем test().then(...).
  2. Обещание говорит вам, что оно будет выполнено в определенный момент времени, не сообщая вам, когда. Затем цепочка будет выполняться всякий раз, когда Promise решает. Это можно увидеть более подробно в returnPromise. Здесь мы возвращаем новое обещание.Тело Promise вызывает метод resolve, когда это делается (в этом случае это мгновенно), вызывая обещание разрешить и выполнить все методы then, прикованные к обещанию. Обычно Promise не будет разрешаться мгновенно, но сначала выполнит асинхронную задачу (например, извлечение данных с сервера).
  3. Это действительно зависит от типа приложения и того, что вы ищете. Ваш нынешний подход не плох сам по себе, если ответственность четко определена.
+0

Я не уверен, правильно ли понимаю ваш аргумент. Я считаю, что исполнителем является часть 'function (resolve, reject)'. В этом нет никакого заявления о возврате; он вызывает только метод 'resolve'. – Sjoerd

+1

Не могли бы вы привести рабочий пример Плункера, потому что я все еще не уверен, что вы имеете в виду. Если вы хотите связать 'then', вы возвращаете новые обещания из своего 'then'. В тексте MDN объясняется, что вы можете либо построить новое обещание, которое разрешает, либо просто возвращает любое значение (которое затем будет автоматически завернуто в Promise и разрешено для вас). Если оставить заявления о выходе, это также не позволит вам передавать информацию с 'then' на' then'. – Sjoerd

+0

Вау, я не знал, что вы можете «вернуть любое значение (которое затем будет автоматически завернуто в обещание и разрешено для вас)». Вы абсолютно правы. Я удалю мои смутные комментарии. – ArneHugo

1

1) Обещание, которое разрешает результат запроса db.post(person).

2) Обратный вызов, переданный в then(...), выполняется, когда вызов db.post() возвращает ответ или генерирует исключение.

3) Не знаю. Я не думаю, что есть общий ответ. Это зависит от того, какой API вы хотите предоставить пользователям этой службы.