承诺链不起作用。为什么?

时间:2013-05-16 00:02:08

标签: javascript windows-8 windows-runtime winjs promise

我有以下代码来选择多个联系人和仅具有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

                    }
                }
            )}
        });

3 个答案:

答案 0 :(得分: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;
        });

答案 1 :(得分: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
    });
});

答案 2 :(得分: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
            });
        }
    });

承诺的链接仅在链的每个步骤(除了最后一个)返回新的承诺时起作用。如果没有承诺返回,你没有另一个异步步骤,所以你可以只处理你需要的东西