Promise中then和catch反回不同Promise对象该如何处理

发布于 2022-09-06 08:29:00 字数 2145 浏览 23 评论 0

代码渣是事实,求指点或者有关问题的信息也行

const fs=require('fs');

const fspro=new Promise((resolve,reject)=>{
    fs.access(__dirname+'//game',(err)=>{
        if(!err){
            resolve(true);
        }else{
            reject(false);
        }
    });
});

fspro.then((result)=>{
    console.log(result);
}).catch((err)=>{
    console.log(err);
});

// 对于一个拥有回调的方法,我们可以轻松的把它改成一个Promise对象
// 他可以使用then 和 catch 其中放置着处理两种不同情况的代码
// 但是有没有发现,实际上then 和 catch 在本例中相当于就是担当了
// true 和 false 代码块的角色
// 这本身并不复杂,但是常见的业务逻辑需要很多的判断
// 比如打开一个文件的逻辑,当然只是举例而已
/**
 * 判断一个文件是否存在
 *    存在            不存在
 *    打开             创建
 * 读取  打不开     打开   创建不了
 *        报错              报错  (假设到这一层就不执行操作了)
 */
// 参考这个逻辑,我们可以编写如下的同步代码(伪代码)
if(hasfile){
    // 存在
    if(fileopen()){
        read();
    }else{
        throw Error('打不开');
    }
}else{
    // 不存在
    if(createfile('test')){
        read();
    }else{
        throw Error('无法创建');
    }
}
// 使用同步代码书写很正常,可是这如何换到Promise中?
const hasfile=new Promise((resolve,reject)=>{
    fs.access(__dirname+'//game',(err)=>{
        if(!err){
            resolve(true);
        }else{
            reject(err);
        }
    });
});
/**
 * 判断一个文件是否存在
 *    存在        不存在
 *    打开         创建
 * 读取  打不开  打开   创建不了
 *       报错             报错  (假设到这一层就不执行操作了)
 */


// 为了保证Promise对象的链式调用,then 和 catch中返回下一个Promise对象
hasfile.then((result)=>{
    // 有文件,执行打开方法
    const fsopenpro=new Promise((resolve,reject)=>{
        fs.open(__dirname+"//game",(err,fd)=>{
            if(!err){
                resolve(fd);
            }else{
                throw Error(err);
            }
        });
    });
    return fsopenpro;
}).catch((err)=>{
    // 没有文件,执行创建方法
    const fscreatepro = new Promise((resolve, reject) => {
        fs.createfile(__dirname + "//game", (err, fd) => {
            if (!err) {
                resolve(fd);
            } else {
                throw Error(err);
            }
        });
    });
    return fscreatepro;
    }) // 到目前为止,代码进行的很顺利,可是到了下一步就不那么容易了
.then((result)=>{
    // fsopenpro 和 fscreatepro 都有可能执行这个then


})
// Promise可不允许你向if那么容易的表达

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

空宴 2022-09-13 08:29:00

Promise适合做一些顺序执行的事情,简单来说就是适合完成一个事件后再去执行另外一件事情(并不单指执行下一个then).如果要进行带容错处理的链式调用,例如判断一个文件是否存在,then部分和catch部分执行代码不一样,则必须保证then和catch返回的Promise也是相同的,不然下一个then中必须判断执行的是哪个分支才可以执行相应的代码.这会变得十分繁琐而且也偏离我们使用Promise的本意.

实际上对于一个问题的结果,例如操作一个文件,我们只关心其结果,完成或者没有完成.但是获取这个结果需要很多个步骤,每个步骤都是有可能出错的,而且出错也有相应的修复逻辑

/**
 * 判断一个文件是否存在
 *    存在            不存在
 *    打开             创建
 * 读取  打不开     打开   创建不了
 *        报错              报错  (假设到这一层就不执行操作了)
 */

完成上面的逻辑,单纯用Promise来写,将会变得十分繁琐,保证Promise最后一个then或者catch是我们要的结果下,
任何比正常逻辑多出的分支必须在一个then或者catch里写完才可以保证最后的结果只有一个,例如上面部分逻辑的伪代码

            hasfile.then(()=>{
                //返回不同效果的Promise,并且包含flag
            let Pro=new Promise(/*对应后续打开文件的代码*/);
                return {
                    hasfile:true,
                    pro:pro
                }
            }).catch(()=>{
                let Pro=new Promise(/*对应后续创建文件的代码*/);
                return {
                    hasfile:false,
                    pro:pro
                }
            }).then((result)=>{
                //这个时候执行的Promise是不一样的
                if(result.flag){
                    //如果还想继续链式调用
                    //只能继续包装一个Promise对象并返回
                    //如果直接把result.pro的Promise执行,那么链式调用就到此结束
                    
                    return new Promise((resolve,reject)=>{
                        //这里执行的是打开的代码,但是代码本体却是在上一个
                        //then里写的
                        result.then((file)=>{
                            resolve(file);
                        }).catch((err)=>{
                            reject(err)
                        })
                    })
                }else{
                    
                }
            })

结果就是,Promise不适合干带有过多逻辑分支或者循环的异步,不然要Generator和async干嘛

初熏 2022-09-13 08:29:00

通过在Promise的返回值里面添加参数,不仅仅依靠then和catch来进行判断处理即可~

殤城〤 2022-09-13 08:29:00

按你的逻辑

fspro.then(
    ()=>{
        //存在,打开,读取
    },
    ()=>{
        //不存在,创建
    }
).catch((err)=>{
    //统一接收报错
})

其实,有更好的逻辑, 先不判断,直接读取

readfile().then(
    (file)=>{
        //读取成功走后续逻辑  
    },
    (err)=>{
        //读取失败,判断错误类型及错误码
        if(文件不存在错误码){
            //创建
        }else{
            //继续抛出错误
            throw err;
        }
    }
)
.catch(function(err){
    //统一接收报错
})
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文