账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    函数返回Promise链式调用,然后继续使用then方法执行,为什么执行顺序不对?
    • 2020-01-01 00:00
    • 11
    30
    0

    代码如下:

    function getPlayerAddress(cameraId) {
                //请求摄像头的直播链接,服务器返回正确结果后进入第一个then函数
                let promise = new Promise(function (resolve, reject) {
                    $.ajax({
                        type: "GET",
                        url: "/cameraManage/getCameraAddress?id=" + cameraId,
                        success: function (data) {
                            if (data.state == 'success') {
                                resolve(data.data);
                            } else {
                                //TODO 错误处理
                                console.log(data.msg);
                            }
                        },
                        error: function (e) {
                            console.log("error");
                        }
                    });
                });
    
                promise
                    .then(function (data) {
                        console.log("进入第1个then,接收到数据如下");
                        console.log(data);
                        serial = data.serial;
                        channelNo = data.channelNo;
                        return new Promise(function (resolve, reject) {
                            if (data.camera) {//服务器直接返回了摄像头直播信息
                                resolve(data);
                            } else if (data.accessToken) {//服务器返回了accessToken
                                resolve(data);
                            } else if (data.appKey && data.appSecret) {//服务器返回了appKey && appSecret
                                $.ajax({
                                    type: "POST",
                                    url: "https://open.ys7.com/api/lapp/token/get",
                                    data: {
                                        appKey: data.appKey,
                                        appSecret: data.appSecret
                                    },
                                    dataType: "json",
                                    success: function (data) {
                                        let tokenData = data.data;
                                        if (data.code == "200" && tokenData) {
                                            resolve(tokenData);
                                            uploadAccessToken(tokenData.accessToken, tokenData.expireTime, 1);
                                        }
                                    },
                                    error: function (e) {
                                        console.log(e);
                                    }
                                });
                            }
                        });
                    })
                    //通过accessToken获取直播链接
                    .then(function (data) {
                        if (data.camera) {
                            console.log("上一步直接返回了camera");
                            return data.camera;
                        }
                        return new Promise((resolve, reject) => {
                            $.ajax({
                                type: "POST",
                                url: "https://open.ys7.com/api/lapp/live/video/list",
                                data: {
                                    accessToken: data.accessToken,
                                },
                                dataType: "json",
                                success: function (data) {
                                    let addressData = data.data;
                                    if (data.code != '200' || !addressData) {
                                        //TODO 错误提示
                                        console.log("直播链接获取失败");
                                        return;
                                    }
    
                                    for (let i = 0; i < addressData.length; i++) {
                                        if (addressData[i].deviceSerial == serial && addressData[i].channelNo == channelNo) {
                                            let argObject = {
                                                serial: addressData[i].deviceSerial,
                                                channelNo: addressData[i].channelNo,
                                                flv: addressData[i].flvAddress,
                                                flvHd: addressData[i].hdFlvAddress,
                                                hls: addressData[i].liveAddress,
                                                hlsHd: addressData[i].hdAddress,
                                                rtmp: addressData[i].rtmp,
                                                rtmpHd: addressData[i].rtmpHd
                                            };
                                            console.log("获取了直播链接");
                                            console.log(argObject);
                                            resolve({"camera": argObject});
                                            uploadYs7CameraAddress(argObject);
                                            break;
                                        }
                                    }
                                },
                                error: function (e) {
                                    console.log(e);
                                }
                            });
                        });
    
                    })
                    //直接使用链式调用,返回的data就没有问题
                    //.then((data)=>{
                    //    console.log('--------------');
                    //    console.log(data);
                });
                return promise;
            }
            
    
    

    我试图使用函数返回promise然后继续使用then来进行链式调用,

    getPlayerAddress(30).then((data) => {
                console.log("<><><><><><><");
                console.log(data);
            });

    但是上面的函数中的执行语句出现在了第二个then中的打印语句之前,换句话说,上述函数先于第二个then执行了,其中捕获的data是第一个then函数传递的值

    这是为什么?????

    0
    打赏
    收藏
    点击回答
    您的回答被采纳后将获得:提问者悬赏的 11 元积分
        全部回答
    • 0
    • ★宇ッ宙★ 普通会员 1楼

      在JavaScript中,Promise链式调用可以用来实现异步编程,而then方法是Promise链式调用中的一个方法,用于在Promise成功或失败时执行一个函数。如果你的函数返回一个Promise,然后继续使用then方法执行,然后返回一个新的Promise,那么执行顺序会受到以下几个因素的影响:

      1. 序列执行:JavaScript是一种后进先出(LIFO)的垃圾回收机制,也就是说,最后一个添加到Promise链中的Promise会被先执行。这是因为JavaScript的异步操作总是会返回一个新的Promise,而不是先执行当前的Promise。因此,当你使用then方法时,它会首先执行返回的Promise,然后才会执行你提供的后续代码。

      2. Promise链的结构:Promise链的结构决定了每个Promise的执行顺序。在JavaScript中,Promise对象有三个属性:pending(未解决)、fulfilled(已解决)和rejected(已拒绝)。在链式调用中,每个Promise都会先执行它在链中的位置,然后如果在链的尾部,再执行后面的Promise。

      例如,如果你有一个函数foo(),它返回一个Promise,你可以使用以下方式调用它:

      javascript const promise = foo(); promise.then(result => { console.log(result); // 输出 "result" }).catch(error => { console.error(error); // 输出 "error" });

      在这个例子中,foo()返回一个Promise,foo().then(result => ...)将这个Promise的Promise链追加到一个Promise对象promise中,然后调用then方法,result参数会先被处理,然后catch方法会被处理。由于promise是链式调用的最后一个Promise,所以result的执行顺序会先于catch方法的执行。

      如果foo()返回的是一个错误,例如foo() => Promise.reject('error'),那么promise的Promise链将被追加到一个错误Promise中,错误Promise的Promise链将先于result的执行,所以result的执行顺序将是在错误Promise执行完后执行的。

      因此,如果在then方法中再次调用foo(),结果将先于任何可能的错误处理代码。例如:

      javascript promise.then(result => { console.log(result); // 输出 "result" }).catch(error => { console.error(error); // 输出 "error" });

      在这个例子中,foo()返回一个错误,所以catch方法将被首先执行,然后result的执行顺序会是先于catch方法的执行。如果在then方法中再次调用foo(),结果将先于catch方法的执行。

    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部