ES6之Promise基础

ES6之Promise基础

为什么会有 Promise 这种东西呢。我们先来看一个例子:

js 复制代码
// 向某位女生发送一则表白短信
// name: 女神的姓名
// onFulffiled: 成功后的回调
// onRejected: 失败后的回调
function sendMessage(name, onFulffiled, onRejected) {
  // 模拟 发送表白短信
  console.log(
    `邓哥 -> ${name}:最近有谣言说我喜欢你,我要澄清一下,那不是谣言😘`
  );
  console.log(`等待${name}回复......`);
  // 模拟 女神回复需要一段时间
  setTimeout(() => {
    // 模拟 有10%的几率成功
    if (Math.random() <= 0.1) {
      // 成功,调用 onFuffiled,并传递女神的回复
      onFulffiled(`${name} -> 邓哥:我是九,你是三,除了你还是你😘`);
    } else {
      // 失败,调用 onRejected,并传递女神的回复
      onRejected(`${name} -> 邓哥:你是个好人😜`);
    }
  }, 1000);
}
sendMessage('小明',(reply)=>{
    console.log(reply);
},(reply)=>{
    console.log(reply);
    sendMessage('小张',(reply)=>{
        console.log(reply);
    },(reply)=>{
        console.log(reply);
        sendMessage('小王',(reply)=>{
            console.log(reply);
        },(reply)=>{
            console.log(reply);
            sendMessage('小李',(reply)=>{
                console.log(reply);
            },(reply)=>{
                console.log(reply);
            })
        })
    })
})

当我们需要通过一个状态去进行下一个状态,再进行下一个状态时,就会出现回调地狱的问题。多个嵌套的回调函数会使得阅读困难。

什么是回调函数呢。我们知道,函数的参数可以传一个函数,为什么要传入一个函数。当我们传入一个函数后,就可以在函数内部进行调用。也就是说,我们不想在一开始就决定这个函数是否使用,而是在一些条件满足之后,才会进行函数的调用,而且是在内部调用。像计时器函数,事件处理函数等都是回调函数。

在函数内部去实现如何进行状态的触发。在函数外部控制状态的一步步过程。外部明显更重要一点。

为什么要有回调函数,因为我们常常遇到执行时间很长的函数,我们不能一直等待它执行。所以我们设置一些条件,把它变为异步的过程,当这些条件满足之后,函数会被执行。在此之前,一直在其他线程待着。

所以,将所有的异步任务都看成一个 Promise 对象。这个对象一开始并不会被执行,在未决阶段,所处的状态叫挂起状态,经过一些条件之后,会分成两种情况。一种被解决,一种被拒绝。导致两种新的状态,完成状态和失败状态。这时就进入了已决阶段。这个过程完成之后,会接着处理下一个异步任务,也就是状态的连续过程。同样也会有两种状态,完成状态和失败状态。究其原因,是把完成和失败两种状态抽离出来,进行更好的控制。

下面是改造成 Promise 后的样子:

js 复制代码
function sendMessage(name) {
  return new Promise((resolve, reject) => {
    // 模拟 发送表白短信
    console.log(
      `邓哥 -> ${name}:最近有谣言说我喜欢你,我要澄清一下,那不是谣言😘`
    );
    console.log(`等待${name}回复......`);
    // 模拟 女神回复需要一段时间
    setTimeout(() => {
      // 模拟 有10%的几率成功
      if (Math.random() <= 0.1) {
        // 成功,调用 onFuffiled,并传递女神的回复
        resolve(`${name} -> 邓哥:我是九,你是三,除了你还是你😘`);
      } else {
        // 失败,调用 onRejected,并传递女神的回复
        reject(`${name} -> 邓哥:你是个好人😜`);
      }
    }, 1000);
  });
}
sendMessage('小明').then((reply)=>{
    console.log(reply);
},(reply)=>{
    console.log(reply);
    sendMessage('小张').then((reply)=>{
        console.log(reply);
    },(reply)=>{
        console.log(reply);
    })
    sendMessage('小王').then((reply)=>{
        console.log(reply);
    },(reply)=>{
        console.log(reply);
        sendMessage('小李').then((reply)=>{
            console.log(reply);
        },(reply)=>{
            console.log(reply);
        })
    })
})

可是依然没有解决回调地狱的问题。注意:状态一旦确定无法更改,如果在 Promise 中设置多个 resolve() 或 reject() ,只会执行第一个,剩下的都是无效代码。

相关推荐
matlab_xiaowang1 天前
Redux 入门:JavaScript 可预测状态管理库
开发语言·javascript·其他·ecmascript
前端摸鱼匠1 天前
Vue 3 的v-bind合并行为:讲解v-bind与普通属性合并的规则
前端·javascript·vue.js·前端框架·ecmascript
REDcker1 天前
浏览器端Web程序性能分析与优化实战 DevTools指标与工程清单
开发语言·前端·javascript·vue·ecmascript·php·js
Linsk1 天前
Java和JavaScript的关系真是雷峰和雷峰塔的关系吗?
java·javascript·oracle
当时只道寻常1 天前
浏览器文本复制到剪贴板:企业级最佳实践
javascript
Alice-YUE1 天前
【js高频八股】防抖与节流
开发语言·前端·javascript·笔记·学习·ecmascript
是上好佳佳佳呀1 天前
【前端(十一)】JavaScript 语法基础笔记(多语言对比)
前端·javascript·笔记
莎士比亚的文学花园1 天前
Linux驱动开发(3)——设备树
开发语言·javascript·ecmascript
01漫游者1 天前
JavaScript函数与对象增强知识
开发语言·javascript·ecmascript
threelab1 天前
Three.js 代码云效果 | 三维可视化 / AI 提示词
开发语言·javascript·人工智能