一、异步函数调用:

//例子:一个名为 createAudioFileAsync() 的函数,它接收一些配置和两个回调函数,然后异步地生成音频文件。一个回调函数在文件成功创建时被调用,另一个则在出现异常时被调用

方法1、

// 成功的回调函数
function successCallback(result) {
  console.log("音频文件创建成功: " + result);
}

// 失败的回调函数
function failureCallback(error) {
  console.log("音频文件创建失败: " + error);
}

createAudioFileAsync(audioSettings, successCallback, failureCallback)

方法2、

/*
*更现代的函数会返回一个 Promise 对象,使得你可以将你的回调函数绑定在该 Promise 上
*如果函数 createAudioFileAsync() 被重写为返回 Promise 的形式,那么我们可以像下面这样简单地调用它
*/

const aa = createAudioFileAsync(audioSettings); 
aa.then(successCallback, failureCallback);

//简写

createAudioFileAsync(audioSettings).then(successCallback, failureCallback);

 

二、链式调用:

//连续执行两个或者多个异步操作时,在上一个操作执行成功后带着返回的结果,开始下一个操作 ,可用Promise链来实现(解决地狱回调问题)

 1)地狱回调:

doSomething( function(result){
      doSomethingElse(result, function(newResult) {
              doThirdThing(newResult, function(finalResult){

                         console.log('Go the final result :'+finalResult);

                },failureCallbake)
       },failureCallbake)
 },failureCallbake)

2)Promis链

doSomething().then(function(result){
          return doSomethingElse(result);
     })

     .then(function(newResult){
         return doThirdThing(newResult);
       })

     .then(function(finalResult){
          console.log('Go the final result:' + finalResult);
      })

   .catch(failureCallback);

//简写:then 里的参数是可选的,catch(failureCallback) 是 then(null, failureCallback) 的缩略形式

  doSomething()

  .then(result => doSomethingElse(result))

  .then(newResult => doThirdThing(newResult))

  .then(finalResult => {
           console.log(`Got the final result: ${finalResult}`);
   })

.catch(failureCallback);

//一定要有返回值,否则,callback 将无法获取上一个 Promise 的结果

三、Catch的后续链式操作

使用一个 catch,在链式操作中抛出一个失败之后,再次进行新的操作

new Promise((resolve, reject) => {
    console.log('初始化');

    resolve();
})
.then(() => {
    throw new Error('有哪里不对了');
        
    console.log('执行「这个1」”');
})
.catch(() => {
    console.log('执行「那个」');
})
.then(() => {
    console.log('执行「这个2」,无论前面发生了什么');
});

/*
*控制台输出:
* 初始化
* 执行「那个」
* 执行「这个2」,无论前面发生了什么
*
*注意:因为抛出了错误 有哪里不对了,所以前一个 执行「这个」 没有被输出
*/

四、错误传递:

1)通常情况下,一遇到异常抛出,浏览器就会顺着Promise 链寻找下一个由 .catch() 指定的回调函数或者onRejected 失败回调函数

//以上所述 的代码工作原理
try {
  let result = syncDoSomething();
  let newResult = syncDoSomethingElse(result);
  let finalResult = syncDoThirdThing(newResult);
  console.log(`Got the final result: ${finalResult}`);
} catch(error) {
  failureCallback(error);
}

2) async/await 语法糖,异步代码

async function foo() {
  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);
  }
}

 

五、组合:

// 1) Promise.resolve() 和 Promise.reject() 是手动创建一个已经 resolve 或者 reject 的 Promise 快捷方法
// 2) Promise.all() 和 Promise.race() 是并行运行异步操作的两个组合式工具

1)发起多个操作,等多个操作全部结束后进行下一步操作:

Promise.all([func1(), func2(), func3()])
.then(([result1, result2, result3]) => { /* use result1, result2 and result3 进行下一步操作*/ });

2)用js实现时序组合:

[func1, func2, func3].reduce((p, f) => p.then(f), Promise.resolve())
.then(result3 => { /* use result3 */ });

3)递归调用一个由异步函数组成的数组时,相当于一个 Promise 链:

Promise.resolve().then(func1).then(func2).then(func3);

4)asnyc /await:

let result;
for (const f of [func1, func2, func3]) {
  result = await f(result);
}
/* use last result (i.e. result3) */

六、嵌套:

嵌套 Promise 是一种可以限制 catch 语句的作用域的控制结构写法,就是嵌套的 catch 仅捕捉在其之前同时还必须是其作用域的 failureres,而捕捉不到在其链式以外或者其嵌套域以外的 error。

 

doSomethingCritical()
  .then(result => doSomethingOptional()
  .then(optionalResult => doSomethingExtraNice(optionalResult))
  .catch(e => {console.log(e.message)}))  // 即使有异常也会忽略,继续运行;(最后会输出)
  .then(() => moreCriticalStuff())
  .catch(e => console.log("Critical failure: " + e.message));// 没有输出
//这个内部的 catch  语句仅能捕获到 doSomethingOptional() 和 doSomethingExtraNice() 的失败,之后就恢复到moreCriticalStuff() 的运行。
//重要提醒:如果 doSomethingCritical() 失败,这个错误仅会被最后的(外部)catch 语句捕获到。

 

 

 

 

 posted on 2020-12-01 12:33  楼顶铁板烧  阅读(561)  评论(0编辑  收藏  举报