2013-05-16 4 views
0

У меня есть следующий код для выбора нескольких контактов и только имена фильтров, которые имеют XYZ. Я использую затем и делаю, чтобы выполнить этот фильтр. В моих контактах есть один контакт с именем XYZ Dude, и я выбираю его также. Не следует ли передавать этот контакт по моему методу после логики фильтрации, которую я применяю в методе then? Любые идеи, что я могу делать неправильно здесьОбещание цепочки не работает. Зачем?

var picker = new Windows.ApplicationModel.Contacts.ContactPicker(); 

     // Open the picker for the user to select a contact. 
     picker.pickMultipleContactsAsync().then(function (contacts) { 
      var contactsStartingWithPrefixPa = contacts.filter(function filterContacts(contact) { 
       if (contact.name.match(/XYZ/)) 
        return true; 
       return false; 
      }); 
     }).done(function (contacts) { 
      // code never reaches here 
      if (contacts != null) { 
       contacts.forEach(function (contact) { 
        if (contact !== null) { 
         // logic to use this contact 

        } 
       } 
      )} 
     }); 

ответ

3

return contactsStartingWithPrefixPa требуется в той функции.

// Open the picker for the user to select a contact. 
    picker.pickMultipleContactsAsync().then(function (contacts) { 
     var contactsStartingWithPrefixPa = contacts.filter(function filterContacts(contact) { 
      if (contact.name.match(/XYZ/)) 
       return true; 
      return false; 
     return contactsStartingWithPrefixPa; 
     }); 
0

Возвращаемое значение contacts.filter не обещание, так что вам не нужно делать какие-либо дополнительные цепочки здесь. Ваш код должен выглядеть так, как и contactsStartingWithPrefixPa это просто проекция контактов, так что вы можете просто сделать итерация непосредственно:

 picker.pickMultipleContactsAsync().done(function (contacts) { 
     var contactsStartingWithPrefixPa = contacts.filter(function filterContacts(contact) { 
      if (contact.name.match(/XYZ/)) 
       return true; 
      return false; 
     }) 

     if (contactsStartingWithPrefixPa.length > 0) { 
      contactsStartingWithPrefixPa.forEach(function (contact) { 
       //Process 
      }); 
     } 
    }); 

Chaining обещаний работает только, когда каждый шаг цепи (за исключением последнего) возвращает новое обещание. Если нет обещания вернуться, у вас нет другого шага асинхронного действия, поэтому вы можете просто обработать то, что вам нужно.

+1

Если функция обратного вызова на обещание возвращает не обещание, он автоматически завершается обещанием этой ценности инфраструктурой. Так что не совсем верно, что у вас должно быть другое обещание, чтобы сделать цепочку. Вы должны что-то вернуть, в противном случае вы получите обещание для неопределенного. –

+0

Спасибо за это разъяснение, Крис. Еще одно обещание всегда необходимо, в конечном счете, но тот факт, что безоговорочное будет автоматически завернуто, полезно знать. –

+0

Да, я тоже этого не знал, похоже, что это может привести к каким-то странным результатам, если вы этого не ожидаете. Вместо того, чтобы просто возвращать 'myObj' и позволять ему автоматически обертываться, может быть яснее явно возвращать' WinJS.Promise.as (myObj) '. – pipedreambomb

1

Если нет веской причины отделить фильтр от «логики для использования этого контакта», , то оба они могут выполняться в одной операции цикла.

var picker = new Windows.ApplicationModel.Contacts.ContactPicker(); 

// Open the picker for the user to select a contact. 
picker.pickMultipleContactsAsync().done(function(contacts) { 
    if(contacts) { 
     contacts.forEach(function(contact) { 
      if(contact.name.match(/XYZ/)) { 
       // logic to use this contact 
      } 
     }); 
    } 
}); 

В противном случае, вы циклически contacts с .filter() затем снова цикл с .forEach().

Если вы действительно должны выделить два аспекта, то (при условии, contacts имеет метод .filter()), вы должны быть в состоянии сделать это следующим образом:

var picker = new Windows.ApplicationModel.Contacts.ContactPicker(); 

// Open the picker for the user to select a contact. 
picker.pickMultipleContactsAsync().then(function(contacts) { 
    return contacts ? contacts.filter(function(contact) { 
     return !!contact.name.match(/XYZ/); 
    }) : []; 
}).done(function(contacts) { 
    contacts.forEach(function(contact) { 
     // logic to use this contact 
    }); 
}); 
Смежные вопросы