美文网首页
回调和Promise

回调和Promise

作者: Zoey_h | 来源:发表于2018-10-15 20:55 被阅读0次

一、什么是回调

程序里面的任务可以根据执行顺序不同分为同步任务异步任务两种。

  • 同步任务是指那些没有被引擎挂起的,在主线程上排队执行的任务,只有前一个任务执行完毕,后一个任务才会执行,如:
function fn1(){
    console.log(1)
}
function fn2(){
    console.log(2)
}
fn1()//1
fn2()//2
  • 异步任务指被引擎挂起的、不在主线程上排队的任务,只有在满足某种条件后,引擎认为可以执行了,异步任务才会进入主线程,如:
function fn1(){
  setTimeout(function(){
        console.log(1)
    },1000)
}
function fn2(){
    console.log(2)
}
fn1()
fn2()//先打出2,再打出1

回调函数(callback)是异步操作最基本的方法,代表着当异步操作完成就调用被传入的函数。基本格式如下:

function fn1(callback){
    callback()
}//fn1是一个异步操作
function fn2(){
    console.log(2)
}
fn1(fn2)

二、什么是回调地狱

  • 回调函数容易理解和实现,但存在一个问题:回调地狱(callback hell)。
  • 回调地狱是指,当多个回调函数嵌套时,容易使得代码程序结构混乱、不容易被读懂,代码非常难看。如:
function fn1(){

}
fn1(function (){
    fn2(function (){
        fn3(function(){
            fn4()
        })
    })
})
  • 解决回调地狱的方法:
    1、给函数命名,减少函数嵌套,如:
function fn1(){

}
function fn2(){
    fn3()
}
function fn3(){
    fn4()
}
function fn4(){

}
fn1(fn2)

2、模块化
这里不展开讲。
3、用Promise

三、Promise

详细用法可参考阮一峰ES6的笔记

所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

Promise对象有以下两个特点:
(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

基本的用法如下:
声明一个函数,返回一个Promise对象,成功就调用resolve(),失败则调用reject()
执行这个函数时,成功就调用.then(arg1,arg2)里的第一个函数arg1,失败则调用第二个函数arg2

function 获取用户信息(name){
    return new Promise(function(resolve,reject){
        if(name === '甲'){
            console.log('原来是小甲')
            resolve('甲')
        }else{
            console.log('谁啊不认识')
            reject('不认识')
        }
    })
}
function 打印信息(data){
    return new Promise(function(resolve,reject){
        console.log(data)
        resolve(data)
    })
}
function 获取好友信息(name){
    return new Promise(function(resolve,reject){
        if(name === '甲'){
            resolve('甲的好友有:张三、李四')
        }else{
            reject('不知道')
        }
    })
}
function 获取失败理由(reason){
        console.log('失败的理由是:'+reason)
        return Promise.reject('不认识')
}
function 修正前面的错误(){
    console.log('我搞不定了,求大神来帮忙')
}
获取用户信息('乙')
    .then(打印信息,获取失败理由)
    .then(获取好友信息,修正前面的错误)
    .then(打印信息)
    .catch(console.log('那就这样吧'))

四、async和await

要获取异步函数的结果时,可以采用await,如:

function 获取用户信息(name){
    return new Promise(function(resolve,reject){
        if(name === '甲'){
            console.log('原来是小甲')
            resolve('甲')
        }else{
            console.log('谁啊不认识')
            reject('不认识')
        }
    })
}
function 打印信息(data){
    return new Promise(function(resolve,reject){
        console.log(data)
        resolve(data)
    })
}
function 获取好友信息(name){
    return new Promise(function(resolve,reject){
        if(name === '甲'){
            resolve('甲的好友有:张三、李四')
        }else{
            reject('不知道')
        }
    })
}
function 获取失败理由(reason){
        console.log('失败的理由是: '+reason)
        return Promise.reject('不认识')
}
function 修正前面的错误(){
    console.log('我搞不定了,求大神来帮忙')
}
try{
    let 用户信息 = await 获取用户信息('乙')
    console.log(用户信息)
}catch(error){
    console.log('失败的理由是: '+error)
}

因为这是用同步的形式来写异步函数,浏览器无法识别是同步还是异步,所以在函数内部使用await时,在声明函数时要在声明前写async,否则会报错。

function buyFruit(){
    setTimeout(function(){
          console.log('apple')
    },5000)
}
function fn(){
    var result = await buyFruit()
    console.log(result)
}
fn()//Uncaught SyntaxError: await is only valid in async function

正确的写法是:

function buyFruit(){
    setTimeout(function(){
          console.log('apple')
    },5000)
}
async function fn(){
    var result = await buyFruit()
    console.log(result)
}
fn()

相关文章

  • 回调和Promise

    一、什么是回调 程序里面的任务可以根据执行顺序不同分为同步任务和异步任务两种。 同步任务是指那些没有被引擎挂起的,...

  • 10. 回调和promise

    异步加载 JSES5 ES6 promise 学习视频记录

  • JavaScript的Promises

    Promise是管理异步的工具,可以管理成功回调和失败回调。 Promise是用来处理一段需要执行的代码的工具。 ...

  • Promise用法总结

    Promise前置储备知识: 函数对象和实例对象(简称对象)同步回调和异步回调(异步回调会将要执行代码块放入队列)...

  • 怎么用promise解决回调和异步

    首先让我们看看下面这题输出什么? 我们得到的结果是:先输出2,后输出1;这是什么原因呢?大家应该都知道定时器是异步...

  • 用promise手写Ajax请求

    首先祭上两篇参考文献XHR对象实例所有的配置、属性、方法、回调和不可变值 使用promise手动封装ajax函数...

  • Promise

    1.为什么需要Promise 回调地狱回调函数中嵌套回调Promise解决了回调地狱 2. Promise 的基本...

  • 如何正确的使用Promise

    promise用法 对比传统回调函数与Pormise的写法 传统回调函数 Promise的写法 Promise要比...

  • ES6(十一)—— Promise(更优的异步编程解决方案)

    目录 说到Promise就不得不说道说道这 —— 回调地狱 Promise —— 解决回调地狱Promise语法规...

  • Promise设计模式

    前言 Promise作为异步编程的一种解决方案,比传统的回调和事件更加强大,也是学习前端所必须要掌握的。作为一个有...

网友评论

      本文标题:回调和Promise

      本文链接:https://www.haomeiwen.com/subject/lasaaftx.html