Javascript For 循环中的承诺链

Javascript Chain of promises in For Loop

我正在使用 twilio 平台...我正在测试我的代码...但我不明白当我尝试从 channelDescriptor 获取频道时会发生什么... 我有这个代码:

function processChannelPage(page)
            {
                var items = page.items;
                that.channels = that.channels || [];

                for (let c = 0, p = Promise.resolve(); c < items.length; c++) 
                {
                    p = p.then(function() {
                        let channelDescriptor = items[c];                        
                        console.log("SID ", channelDescriptor.sid);
                        
                         
                        getPreviousMessages(channelDescriptor, that)
                        .then(function() {
                            console.log("resuelto msg", channelDescriptor.sid);
                            return Promise.resolve();
                        }); 

                    });    
                }

                ..............
            }

            that.client.getUserChannelDescriptors().then(function (paginator) {
                processChannelPage(paginator);
            });

    function getPreviousMessages(channelDescriptor, chat) {
        return new Promise(resolve => { 
            console.log("p2.....step0.....", channelDescriptor.sid);     
            console.log("p2.....step1.....", channelDescriptor.sid);
            let promise = chat.getChannel(channelDescriptor.sid); 
            console.log(promise);       
            return promise.then(channel => {
                console.log("p2.....step2.....", channelDescriptor.sid); 
                return channel;
            });
        });
    }
 

    TwilioChat.prototype.getChannel = function (channel_sid) {
        console.log("I am in getChannel.....");
        for (var channel in this.channels) {
            if (this.channels[channel].sid == channel_sid) {
                return this.channels[channel].getChannel();
            }
        }
        return null;
    };

我知道 TwilioChat.prototype.getChannel returns 是一个 Promise,然后我知道我需要像这样使用 THEN 来评估这个 Promise

chat.getChannel(channelDescriptor.sid).then

但我看到了这个结果:

SID  CH09c567eeebab4dabb5fa8594a44d774e
twilio_helper.js:147 p2.....step0..... CH09c567eeebab4dabb5fa8594a44d774e
twilio_helper.js:148 p2.....step1..... CH09c567eeebab4dabb5fa8594a44d774e
twilio_helper.js:388 I am in getChannel.....
twilio_helper.js:392 Promise {<pending>}
twilio_helper.js:72 SID  CH369ca3cc46d74886b031a52fd2e7dc29
twilio_helper.js:147 p2.....step0..... CH369ca3cc46d74886b031a52fd2e7dc29
twilio_helper.js:148 p2.....step1..... CH369ca3cc46d74886b031a52fd2e7dc29
twilio_helper.js:388 I am in getChannel.....
twilio_helper.js:392 Promise {<pending>}
twilio_helper.js:150 p2.....step2..... CH09c567eeebab4dabb5fa8594a44d774e
twilio_helper.js:150 p2.....step2..... CH369ca3cc46d74886b031a52fd2e7dc29

我的问题是...为什么这个日志 twilio_helper.js:150 p2.....step2 我看到了我的承诺链之外。 我需要看到这个结果:

SID  CH09c567eeebab4dabb5fa8594a44d774e
twilio_helper.js:147 p2.....step0..... CH09c567eeebab4dabb5fa8594a44d774e
twilio_helper.js:148 p2.....step1..... CH09c567eeebab4dabb5fa8594a44d774e
twilio_helper.js:388 I am in getChannel.....
twilio_helper.js:392 Promise {<pending>}
twilio_helper.js:150 p2.....step2..... CH09c567eeebab4dabb5fa8594a44d774e

twilio_helper.js:72 SID  CH369ca3cc46d74886b031a52fd2e7dc29
twilio_helper.js:147 p2.....step0..... CH369ca3cc46d74886b031a52fd2e7dc29
twilio_helper.js:148 p2.....step1..... CH369ca3cc46d74886b031a52fd2e7dc29
twilio_helper.js:388 I am in getChannel.....
twilio_helper.js:392 Promise {<pending>}
twilio_helper.js:150 p2.....step2..... CH369ca3cc46d74886b031a52fd2e7dc29

第一个 channelDescriptor....所有承诺执行....下一个 ChannelDescriptor...所有承诺执行...换句话说,循环按每个 channelDescriptor 的顺序前进... 请我只需要承诺...而不是 Async/Await... 因为我需要它也适用于 IExplorer。 你能帮我实现这个承诺吗? 非常感谢!

好的!!!! 好的,我像这些修改一样更改我的代码....

TwilioChat.prototype.getChannel = function(channel_sid){
    console.log("I am in getChannel.....");
    for (var channel in this.channels) {
        if (this.channels[channel].sid == channel_sid) {
            return this.channels[channel].getChannel();
        }
    }
    reject("error");
};


function getPreviousMessages(channelDescriptor, chat) {
    return new Promise(resolve => { 
        console.log("p2.....step0.....", channelDescriptor.sid);     
        console.log("p2.....step1.....", channelDescriptor.sid);
        let promise = chat.getChannel(channelDescriptor.sid); 
        console.log(promise);       
        return promise.then(channel => {
            console.log("p2.....step2.....", channelDescriptor.sid); 
            resolve(channel); // I Resolve my New Promise
        });
    });
}

但我的测试总是这样:

我明白了....这段代码日志....

SID  CH09c567eeebab4dabb5fa8594a44d774e
twilio_helper.js:147 p2.....step0..... CH09c567eeebab4dabb5fa8594a44d774e
twilio_helper.js:148 p2.....step1..... CH09c567eeebab4dabb5fa8594a44d774e
twilio_helper.js:388 I am in getChannel.....
twilio_helper.js:392 Promise {<pending>}
twilio_helper.js:72 SID  CH369ca3cc46d74886b031a52fd2e7dc29
twilio_helper.js:147 p2.....step0..... CH369ca3cc46d74886b031a52fd2e7dc29
twilio_helper.js:148 p2.....step1..... CH369ca3cc46d74886b031a52fd2e7dc29
twilio_helper.js:388 I am in getChannel.....
twilio_helper.js:392 Promise {<pending>}
twilio_helper.js:150 p2.....step2..... CH09c567eeebab4dabb5fa8594a44d774e
twilio_helper.js:150 p2.....step2..... CH369ca3cc46d74886b031a52fd2e7dc29

p2.....Step2.....在我的循环之外....真的我不明白。

避免 getPreviousMessages 中的 Promise constructor antipattern,确保 getChannel 总是 returns 承诺,并且不要忘记 return 你的承诺来自then 中的回调 processChannelPage.

function processChannelPage(page) {
    var items = page.items;
    that.channels = that.channels || [];

    for (let c = 0, p = Promise.resolve(); c < items.length; c++) {
        p = p.then(function() {
            let channelDescriptor = items[c];                        
            console.log("SID ", channelDescriptor.sid);

            return getPreviousMessages(channelDescriptor, that).then(function() {
//          ^^^^^^
                console.log("resuelto msg", channelDescriptor.sid);
            }); 
        });
    }
    …
    return p;
}

that.client.getUserChannelDescriptors().then(function (paginator) {
    return processChannelPage(paginator);
//  ^^^^^^
});

function getPreviousMessages(channelDescriptor, chat) {
    console.log("p2.....step0.....", channelDescriptor.sid);     
    console.log("p2.....step1.....", channelDescriptor.sid);
    let promise = chat.getChannel(channelDescriptor.sid); 
    console.log(promise);       
    return promise.then(channel => {
//  ^^^^^^
        console.log("p2.....step2.....", channelDescriptor.sid); 
        return channel;
    });
}

TwilioChat.prototype.getChannel = function (channel_sid) {
    console.log("I am in getChannel.....");
    for (var channel in this.channels) {
        if (this.channels[channel].sid == channel_sid) {
            return this.channels[channel].getChannel();
        }
    }
    return Promise.resolve(null);
//         ^^^^^^^^^^^^^^^^    ^
};