JS Promise用法

来源:互联网 发布:域名服务器 编辑:程序博客网 时间:2024/06/06 19:20

JS Promise用法


Promise概述

promise对象用于异步计算,相比于回调函数,promise对象除了规定的方法都是不可用的,牺牲了一定自由度的同时,可以将复杂的异步处理模式化。

句法

Promise( /* executor */ function(resolve, reject) { ... } );

new一个Promise构造器进行实例化,返回一个promise对象:

var promise = new Promise(function(resolve, reject) {    // 异步处理    // 处理结束后、调用resolve 或 reject});

Promise 状态

一个promise实例有一下几个状态(默认是Promises/A+的描述状态):

  • pending:初始化阶段,没有fulfilled或者是rejected
  • fulfilled:操作成功完成(promise resolve)
  • rejected:操作失败(promise reject)

如果promise处于pending状态,处理promise的处理模块(handler)就会处于排队状态pending状态可以变成fulfilled或者rejected状态,不过fulfilled状态和rejected状态是不可相互转换的。promise从pending状态到fulfilled或者rejected状态,.then处理只会被调用一次,比如:

var promise = new Promise(function(resolve,reject){var n = 6if(n<3)resolve(console.log('yes')); //成功了调用回调函数elsereject(new Error(console.log('this is an error'))); //失败调用reject并抛出异常})var promise = new Promise(function(resolve,reject){    var i = 2;    if(i<3)    resolve(setTimeout("alert('hello')",5000));    else    reject(new Error(console.log('no')));})promise.then(console.log('ok'));

Promise 链

Promise.prototype.then()和Promise.prototype.then()方法返回promise对象,就成为promise链,如图:

chains

方法

  • Promise.all()

返回promise在迭代声明中是fulfilled还是reject,如果是fulfill,就返回一个数组,值是按照在迭代器中的顺序成功了的promises。如果返回不成功(reject)的promise,返回迭代器中第一个失败对象的原因。这个方法可以使用在有多个promise的情况下。

  • Promise.race()

如有有一个迭代中的promise被fulfilled或者rejected,这个方法立即返回处理值

  • Promise.reject()

返回被reject的原因

  • Promise.resolve()

返回处理成功的promise对象

例子

'use strict';var promiseCount = 0;function testPromise() {    var thisPromiseCount = ++promiseCount;    var log = document.getElementById('log');    log.insertAdjacentHTML('beforeend', thisPromiseCount +        ') Started (<small>Sync code started</small>)<br/>');    // We make a new promise: we promise a numeric count of this promise, starting from 1 (after waiting 3s)    var p1 = new Promise(        // The resolver function is called with the ability to resolve or        // reject the promise        function(resolve, reject) {            log.insertAdjacentHTML('beforeend', thisPromiseCount +                ') Promise started (<small>Async code started</small>)<br/>');            // This is only an example to create asynchronism            window.setTimeout(                function() {                    // We fulfill the promise !                    resolve(thisPromiseCount);                }, Math.random() * 2000 + 1000);        }    );    // We define what to do when the promise is resolved/fulfilled with the then() call,    // and the catch() method defines what to do if the promise is rejected.    p1.then(        // Log the fulfillment value        function(val) {            log.insertAdjacentHTML('beforeend', val +                ') Promise fulfilled (<small>Async code terminated</small>)<br/>');        })    .catch(        // Log the rejection reason        function(reason) {            console.log('Handle rejected promise ('+reason+') here.');        });    log.insertAdjacentHTML('beforeend', thisPromiseCount +        ') Promise made (<small>Sync code terminated</small>)<br/>');}

浏览器兼容

Feature Chrome Edge Firefox InternetExplorer Opera Safari Servo Promise 32.0 (Yes) 29.0 No support 19 7.1 No support

项目中的使用

项目中使用Angular,链式操作异步请求也是使用的promise($q)
代码片段:

applicationService.getApplications().then(function(resp){        var data = resp.data.resources;        var promises = [];        $scope.total = resp.data.total_results;        angular.forEach(data,function(app,i) {            promises.push($scope.whatState(app));        })        $q.all(promises).then(function(){            $scope.fillDatenation($scope.nrOfStartedApps,$scope.nrOfStoppedApps,$scope.nrOfAbnormal);        })    })$scope.whatState = function(app) {        var defer = $q.defer();        if (app.entity.state === 'STOPPED') {            $scope.nrOfStoppedApps++;            defer.resolve();        } else {                applicationService.getInstanceInfo(app.metadata.guid).then(function (response) {                var data = response.data;                var n = 0;                angular.forEach(data, function (_data) {                    if (_data.state =="RUNNING") {                        n++;                    }                })                if (n > 0) {                    $scope.nrOfStartedApps++;                } else {                    $scope.nrOfAbnormal++;                }                defer.resolve();            })        }        return defer.promise;    }

本文参考

MDN :
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise

JS Promise迷你书:
http://www.kancloud.cn/kancloud/promises-book/44251

0 0
原创粉丝点击