0

我有以下代码来选择多个联系人,并且只过滤具有 XYZ 的名称。我正在使用然后完成这个过滤器。在我的联系人中,有一位名叫XYZ Dude的联系人,我也在选择它。在我在 then 方法中应用过滤逻辑之后,不应该在我的 done 方法中传递这个联系人吗?任何想法我在这里可能做错了什么

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

                    }
                }
            )}
        });
4

3 回答 3

3

return contactsStartingWithPrefixPa在 then 函数中是必需的。

   // 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;
        });
于 2013-05-16T02:46:07.523 回答
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
    });
});
于 2013-05-16T20:31:25.970 回答
0

Contacts.filter 的返回值不是一个承诺,所以你不需要在这里做任何额外的链接。您的代码应如下所示,因为 contactsStartingWithPrefixPa 只是联系人的投影,因此您可以直接进行 forEach 迭代:

        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
            });
        }
    });

只有当链中的每一步(除了最后一步)都返回一个新的 Promise 时,Promise 的链接才有效。如果没有返回的承诺,则您没有另一个异步步骤,因此您可以立即处理您需要的内容

于 2013-05-16T15:53:21.583 回答