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

Javascript 承诺链接不起作用。为什么?,javascript,windows-8,windows-runtime,winjs,promise,Javascript,Windows 8,Windows Runtime,Winjs,Promise,我有以下代码来选择多个联系人,并且只筛选具有XYZ的姓名。我使用then和done来完成这个过滤器。在我的联系人中,有一个联系人名为XYZ Dude,我也在选择它。在我在then方法中应用过滤逻辑之后,是否应该在我的done方法中传递此联系人?你知道我做错了什么吗 var picker = new Windows.ApplicationModel.Contacts.ContactPicker(); // Open the picker for the user to selec

我有以下代码来选择多个联系人,并且只筛选具有XYZ的姓名。我使用then和done来完成这个过滤器。在我的联系人中,有一个联系人名为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

                    }
                }
            )}
        });

then功能中需要返回触点STARTINGWITHPREFIXPA

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

then功能中需要返回触点STARTINGWITHPREFIXPA

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

contacts.filter的返回值不是承诺,因此您不需要在此处执行任何其他链接。您的代码应该是这样的,因为contactsStartingWithPrefixPa只是一个contacts的投影,所以您可以直接执行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
            });
        }
    });

承诺链只有在链的每一步(最后一步除外)返回新承诺时才起作用。如果没有返回的承诺,那么您就没有其他异步步骤,因此您可以直接处理您需要的内容。contacts.filter的返回值不是承诺,因此您不需要在此处执行任何其他链接。您的代码应该是这样的,因为contactsStartingWithPrefixPa只是一个contacts的投影,所以您可以直接执行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
            });
        }
    });

承诺链只有在链的每一步(最后一步除外)返回新承诺时才起作用。如果没有返回的承诺,您就没有其他异步步骤,因此您可以直接处理您需要的内容

,除非有充分的理由将过滤器与“使用此触点的逻辑”分开,否则这两个步骤都可以在一个循环操作中执行

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
            }
        });
    }
});
否则,您将使用
.filter()
联系人中循环,然后使用
.forEach()
再次循环

如果您确实必须将两个方面分开,那么(假设
联系人
具有
.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
    });
});

除非有充分的理由将过滤器与“使用此触点的逻辑”分开,否则两者都可以在一个循环操作中执行

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
            }
        });
    }
});
否则,您将使用
.filter()
联系人中循环,然后使用
.forEach()
再次循环

如果您确实必须将两个方面分开,那么(假设
联系人
具有
.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
    });
});

如果承诺上的回调函数返回非承诺,则基础结构会自动将其包装为该值的承诺。因此,严格来说,你必须有另一个承诺才能进行链接,这并不是真的。你应该归还一些东西,否则你会得到一个未定义的承诺。谢谢你的澄清,克里斯。最终,总是需要另一个承诺,但不承诺会自动包装这一事实很有帮助。是的,我也不知道,如果你没有预料到的话,听起来可能会产生一些奇怪的结果。与其简单地返回
myObj
并让它自动包装,不如显式地返回
WinJS.Promise.as(myObj)
。如果Promise上的回调函数返回非Promise,则基础结构会自动将其包装为该值的Promise。因此,严格来说,你必须有另一个承诺才能进行链接,这并不是真的。你应该归还一些东西,否则你会得到一个未定义的承诺。谢谢你的澄清,克里斯。最终,总是需要另一个承诺,但不承诺会自动包装这一事实很有帮助。是的,我也不知道,如果你没有预料到的话,听起来可能会产生一些奇怪的结果。与其简单地返回
myObj
并让它自动包装,不如显式地返回
WinJS.Promise.as(myObj)