zoukankan      html  css  js  c++  java
  • 进击Node.js基础(二)promise

    一.Promise—Promise似乎是ES6中的规范

    PROMISE的语言标准,PROMISE/A+规范,如何使用,在什么场景下使用
    Promise时JS对异步操作场景提出的解决方案(回调,观察者模式等等都是一些方案)
    Promise以同步的方式写代码,执行异步的操作,Promise对象和普通JS对象没什么区别,它有三种状态1:未完成2:已完成3:失败
    A+规范和A的不同点
    -A+规范通过thenable来区分promise对象
    -A+定义onFulfilled/onRejected必需是作为一个函数来调用,并且调用过程要是异步的
    -A+严格定义了then方法链式调用时onFulfilled/onRejected的调用顺序

    JS动画settimeout,setinterval,requestAnimationFrame

    npm install bluebird (blue时一个promise库)

    npm install 在哪个目录写包就会安装在哪个目录(全局估计不是)

    Promise then方法
    promiseObj.then(onFullfilled,onRejected)
    返回的必需是一个promise对象
     Javascript的特点是异步,Javascript不能等待,如果你实现某件需要等待的事情,你不能停在那里一直等待结果回来,相反,底线是使用回调callback:你定义一个函数,这个函数只有等到结果可用时才能被调用。
    
     这种回调模型对于好的代码组织是没有问题的,但是也可以通过从原始回调切换到promise解决很多问题,将promise看成是一个标准的数据容器,这样会简化你的代码组织,可以成为基于promise的架构。
    
    什么是Promise?
    
     一个promise是一个带有".then()"方法的对象,其代表的是一个操作的结果可能还没有或不知道,无论谁访问这个对象,都能够使用".then()"方法加入回调等待操作出现成功结果或失败时的提醒通知,。
    
     那么为什么这样做好处优于回调呢?标准的回调模式在我们处理请求时需要同时提供回调函数:
    
    request(url, function(error, response) { 
      // handle success or error.
    });
    doSomethingElse(); 
     很不幸,这段代码意味着这个request函数并不知道它自己什么时候能够完成,当然也没有必要,我们最终通过回调传递结果。这会导致多个回调形成了嵌套回调,或者称为回调陷阱。
    
    queryTheDatabase(query, function(error, result) { 
      request(url, function(error, response) {
        doSomethingElse(response, function(error, result) {
          doAnotherThing(result, function(error, result) {
            request(anotherUrl, function(error, response) {
              ...
            });
          });
        });
      });
    });
     Promise能够解决这种问题,允许低层代码创建一个request然后返回一个对象,其代表着未完成的操作,让调用者去决定应该加入什么回调。
    
     
    
    Promise是什么?
    
     promise是一个异步编程的抽象,它是一个返回值或抛出exception的代理对象,一般promise对象都有一个then方法,这个then方法是我们如何获得返回值(成功实现承诺的结果值,称为fulfillment)或抛出exception(拒绝承诺的理由,称为rejection),then是用两个可选的回调作为参数,我们可以称为onFulfilled和OnRejected:
    
    var promise = doSomethingAync()
    promise.then(onFulfilled, onRejected)
    
     当这个promise被解决了,也就是异步过程完成后,onFulfilled和OnRejected中任何一个将被调用,
    
     因此,一个promise有下面三个不同状态:
    
    pending待承诺 - promise初始状态
    fulfilled实现承诺 - 一个承诺成功实现状态
    rejected拒绝承诺 - 一个承诺失败的状态
     以读取文件为案例,下面是使用回调实现读取文件后应该做什么事情(输出打印):
    
    readFile(function (err, data) {
      if (err) return console.error(err)
      console.log(data)
    })
     如果我们的readFile函数返回一个promise,那么我们可以如下实现同样的逻辑(输出打印):
    
    var promise = readFile()
    promise.then(console.log, console.error)
    
     这里我们有了一个值promise代表的是异步操作,我们能够一直传递这个值promise,任何人访问这个值都能够使用then来消费使用它,无论这个值代表的异步操作是否完成或没有完成,我们也能保证异步的结果不会改变,因为这个promise代表的异步操作只会执行一次,状态是要么fulfilled要么是rejected。
    
     
    
    理解Promise
    
     Promise可能是不同于日常直觉,为了理解它,一些重要原理必须记牢: .then()总是返回一个新的promise.,如下面代码:
    
    var promise = readFile()
    var promise2 = promise.then(readAnotherFile, console.error)
    
     这里then的参数readAnotherFile, console.error是代表异步操作成功后的动作onFulfilled或失败后的动作OnRejected,也就是说,读取文件成功后执行readAnotherFile函数,否则失败打印记录错误。这种实现是两个中只有一种可能。
    
     我们再看下面上述代码如下:
    
    var promise = readFile()
    var promise2 = promise.then(function (data) {
      return readAnotherFile() // 如果readFile成功,执行readAnotherFile
    }, function (err) {
      console.error(err) // 如果readFile不成功,记录,但是还是执行readAnotherFile
      return readAnotherFile()
    })
    promise2.then(console.log, console.error) // readAnotherFile函数的执行结果
     因为then返回一个promise,它意味着promise能够被chain串行链条花,这样能避免回调地狱:
    
    readFile()
      .then(readAnotherFile)
      .then(doSomethingElse)
      .then(...)
     Promise法则有两部分必须分离:
    
     (1).then()总是返回一个新的promise,每次你调用它,它不管回调做什么,因为.then()在回调被调用之前已经给了你一个承诺promise,回调的行为只影响承诺promise的实施,如果回调返回一个值,那么promise将使用那个值,如果这个值是一个promise,返回这个promise实施后的值给这个值,如果回调抛出错误,promise将拒绝错误。
    
     (2)被.then()返回的promise是一个新的promise,它不同于那些.then()被调用的promise,promise长长的链条有时会好些隐藏这个事实,不管如何,每次.then()调用都会产生一个新的promise,这里必须注意的是你真正需要考虑的是你最后调用.then()可能代表失败,那么如果你不捕获这种失败,那么容易导致你的错误exception消失。
    
     一些人认为.then()串联链条调用很类似fluent风格,但是长长的promise链条会让人迷惑,最后切分为一个个有意义的函数:
    
    function getTasks() { 
      return $http.get('http://example.com/api/v1/tasks')
        .then(function(response) {
          return response.data;
        });
    }
     
    function getMyTasks() { 
      return getTasks()
        .then(function(tasks) {
          return filterTasks(tasks, {
            owner: user.username
          });
        });
    }
     在这个例子中,两个函数各自获得一个promise,携带了一个回调函数。
    
    有趣的Promise
    
     同样的promise能够接受任何数目的回调,当一个Promise被解决实施后,其中所有回调函数都会被调用,此外,一个promise在被解决实施后,甚至可以接受一个新的回调,这些回调完成能以正常方式被调用,这就允许我们使用回调实现简单形式的缓存:
    
    var tasksPromise; 
    function getTasks() { 
      taskPromise = taskPromise || getTasksFromTheServer();
      return taskPromise;
    }
     这个案例中,getTasks()函数可以被任意次数调用,它总是返回铜牙的promise,其中函数getTasksFromTheServer()却只是被调用一次。
  • 相关阅读:
    borderInterpolate()函数
    cvtColor(src, src_gray, CV_BGR2GRAY)报错
    用OpenCV读取摄像头
    OpenCV的视频输入和相似度测量
    C++ main函数中参数argc和argv含义及用法
    OpenCV的视频读取
    MySql与Oracle的几个主要区别
    OLTP与OLAP的介绍(理论知识)
    IDEA激活
    short i =1; i=i+1与short i=1; i+=1的区别
  • 原文地址:https://www.cnblogs.com/cndotabestdota/p/5756948.html
Copyright © 2011-2022 走看看