为什么要使用Promise,Promise的优点

1.指定回调函数的方式更加灵活: 
  旧的: 必须在启动异步任务前指定
  promise: 启动异步任务 => 返回promie对象 => 给promise对象绑定回调函数(甚至可以在异步任务结束后指定) 

假设现在有一个名为 createAudioFileAsync() 的函数,如果给出一些配置和两个回调函数,这个函数能异步地生成音频文件。一个回调函数是文件成功创建时的回调,另一个则是出现异常时的回调。

  • 不使用Promise,回调函数必须先指定
    // 成功的回调函数
    function successCallback (result) {
        console.log('声音文件创建成功: ' + result)
    }
    // 失败的回调函数
    function failureCallback (error) {
        console.log('声音文件创建失败: ' + error)
    }
    /* 1.1 使用纯回调函数 */
    createAudioFileAsync(audioSettings, successCallback, failureCallback)
  • 使用Promise
    const promise = createAudioFileAsync(audioSettings)
    promise.then(successCallback, failureCallback)
    
    // 可简写为
    createAudioFileAsync(audioSettings).then(successCallback, failureCallback);
    

    可以在异步操作完成后再指定回调函数

  • setTimeout(() => {
        promise.then(successCallback, failureCallback)
    }, 3000)

2.支持链式调用(将异步操作以同步操作的流程表达出来), 可以解决回调地狱问题
  什么是回调地狱? 回调函数嵌套调用, 外部回调函数异步执行的结果是嵌套的回调函数执行的条件
  回调地狱的缺点?  不便于阅读 / 不便于异常处理
  解决方案? promise链式调用
  终极解决方案? async/await 

  • 回调地狱 
  • doSomething(function (result) {
        doSomethingElse(result, function (newResult) {
            doThirdThing(newResult, function (finalResult) {
                console.log('Got the final result: ' + finalResult)
            }, failureCallback)
        }, failureCallback)
    }, failureCallback)
  • 使用promise的链式调用解决回调地狱
  •  doSomething().then(function (result) {
             return doSomethingElse(result)
         })
         .then(function (newResult) {
             return doThirdThing(newResult)
         })
         .then(function (finalResult) {
             console.log('Got the final result: ' + finalResult)
         })
         .catch(failureCallback)
    
    ======
    
    // 箭头函数写法
    doSomething()
        .then(result => doSomethingElse(result))
        .then(newResult => doThirdThing(newResult))
        .then(finalResult => {
            console.log(`Got the final result: ${finalResult}`)
        })
        .catch(failureCallback)
  • async/await: 回调地狱的终极解决方案
  • async function request () {
        try {
            const result = await doSomething()
            const newResult = await doSomethingElse(result)
            const finalResult = await doThirdThing(newResult)
            console.log('Got the final result: ' + finalResult)
        } catch (error) {
            failureCallback(error)
        }
    }

    Promise的缺点

  • 无法取消Promise,一旦新建它就会立即执行,无法中途取消。
  • 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。
  • 当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)
const someAsyncThing = function() {
  return new Promise(function(resolve, reject) {
    // 下面一行会报错,因为x没有声明
    resolve(x + 2);
  });
};

someAsyncThing().then(function() {
  console.log('everything is great');
});

setTimeout(() => { console.log(123) }, 2000);
// Uncaught (in promise) ReferenceError: x is not defined
// 123

上面代码中,someAsyncThing函数产生的 Promise 对象,内部有语法错误。浏览器运行到这一行,会打印出错误提示ReferenceError: x is not defined,但是不会退出进程、终止脚本执行,2 秒之后还是会输出123。这就是说,Promise 内部的错误不会影响到 Promise 外部的代码,通俗的说法就是“Promise 会吃掉错误”。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wflynn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值