Promise实现之q.js

q.js在nodejs里是一个非常流行的promise库,支持浏览器端使用,详情请点击这里



q.jsasync要解决的问题差不多,都是解决回调函数的嵌套问题,避免嵌套层级太深导致一系列的问题.只是q.js是以promise来实现回调的扁平化,而async则是通过流程来控制多个异步回调的处理.

q.js的所有方法操作的对象都得是一个promise对象,下面来说说怎么用q来创建promise对象

下面所有实例统一在nodejs环境里执行,请执行下面命令安装q.js,然后引用它

npm install q --save
var q = require('q'),
    fs = require('fs');

下面会用到文件模块,所以也要引用

创建promise对象

q.fcall 传递给此方法一个返回值的函数或者一个defer实例,将会创建一个promise对象

var promise = q.fcall(function(){
    return [10, 20];
});

var promise1 = q.fcall(function(){
    var deferred = q.defer();
    fs.readFile('../data/file2.txt', 'utf8', deferred.makeNodeResolver());
    return deferred.promise;
});

q.defer 通过延迟对象来创建promise对象

var getFile = function(){
    var deferred = q.defer();
    fs.readFile('../data/file.txt', 'utf8', function(err, content){
        if(err){
            deferred.reject(new Error(err));
        }else{
            deferred.resolve(content);
        }
    });
    return deferred.promise;
}

q.promise 传递此方法一个函数来创建promise对象

var getFilePromise = function(){
    return q.promise(function(resolve, reject, notify){
        fs.readFile('../data/file.txt', 'utf8', function(err, content){
            if(err){
                reject(new Error(err));
            }else{
                resolve(content);
            }
        });
    })
}

说完了创建promise对象,然后我们来看看怎么使用这些对象吧

使用promise对象

最简单的使用方法就是直接使用then方法,传入一个成功回调与一个异常回调

// fcall创建的promise

promise.then(function(msg){
    console.log(msg);
}, function(err){
    // do stuff
});

// q.defer创建的promise
getFile().then(function(msg){
    console.log(msg);
}, function(err){
    // do stuff
})

// q.promise创建的promise中q.defer使用一样

q.all 使用此方法可以保证执行多个异步方法之后执行回调

q.all([promise, promise1]).then(function(msg){
    console.log('normal', msg);
}, function(err){
    console.log(err);
})

上面的q.all方法成功返回的结果会返回一个包含所有异步方法结果的数组,出现一个异步方法异常则执行错误回调方法.

  • 注意q.all 里的promise数组支持不带延迟对象以及延迟对象

q.when 使用此方法执行不带延迟对象以及延迟对象promise,不支持传递数组内带延迟对象

q.when(promise1, function(msg){
    log('when' + msg);
},function(err){
    console.log(err);
})

q.when(promise, function(msg){
    log('when' + msg);
},function(err){
    console.log(err);
})

q.when([promise, promise], function(msg){
    log('when' + msg);
},function(err){
    console.log(err);
})

返回的结果处理跟q.all一样

  • 注意q.when 不支持数组内传递延迟对象

q.nfcall | q.nfapply 这两方法是对nodejs里异步方法的适配,不用写上面promise对象定义里的resolve及reject等

q.nfcall(fs.readFile, '../data/file.txt', 'utf8').then(function(msg){
    console.log('nfcall', msg);
})

q.nfapply(fs.readFile, ['../data/file.txt', 'utf8']).then(function(msg){
    console.log('nfapply', msg);
})

其实nfcall = node function callnfapply = node function apply,传递的传递参考callapply方法,回调处理跟上面的一样

当回调函数内出现异常时,回调异常函数是catch不到的,这里q提供了一个fail方法

var getFileHandy = function(){
    var deferred = q.defer();
    fs.readFile('../data/file1.txt', 'utf8', deferred.makeNodeResolver());
    return deferred.promise;
}
getFileHandy().then(function(msg){
    console.log(msg);
    throw new Error('demo exception');
}).fail(function(err){
    // 此处可以catch 所有的异常
    console.log(err);
});

以上都是单一的异步方法调用,下面说说q里的链式调用

promise1.then(function(msg){
    return getFile();
}).
then(function(msg){
    return getFileHandy()
    .then(function(data){
        return getFilePromise();
    })
    .then(function(content){
        console.log('>>' + content);
        throw new Error('haha error!');
    });
}).
fail(function(err){
    console.log('err>>' + err);
});

所谓的链式调用就是在成功回调内返回一个新的promise对象,假如之后的回调不需要获取闭包内容的话,可以直接返回,否则可以接着写then方法调用

总结

q.js是一个非常好用的promise实现,前后端都可以用,像ng里就有一个$q的实现,强烈推荐大家使用这个.

时间: 2024-12-24 08:47:43

Promise实现之q.js的相关文章

node.js中使用q.js实现api的promise化

  这里我们看看怎么用q.js 实现node api的promise. 一.万事开始皆为install 代码如下: npm install q 二.标准node style api 的promise化方法 1.使用Q.nfcall 相对于Q.fcall ,Q.nfcall 就是node 的Q.fcall. 代码如下: var FS = require('fs'), Q = require('q'), colors = require('colors'), file = 'example.txt'

node.js中使用q.js实现api的promise化_node.js

关于啥是promise以及promise解决的是啥问题,敬请体验node的回调异步编码大法,顺带移步http://wiki.commonjs.org/wiki/Promises/A 看看是咋定义的,在此不再赘述. 这里我们看看怎么用q.js 实现node api的promise. 一.万事开始皆为install 复制代码 代码如下: npm install q 二.标准node style api 的promise化方法 1.使用Q.nfcall 相对于Q.fcall ,Q.nfcall 就是n

利用q.js实现node 常用api的promise化

这里我们看看怎么用q.js 实现node api的promise. 1.万事开始皆为install npm install q 2.标准node style api 的promise化方法 1.使用Q.nfcall 相对于Q.fcall ,Q.nfcall 就是node 的Q.fcall.    代码如下 复制代码 var FS = require('fs'),     Q   = require('q'),     colors = require('colors'),     file =

异步JavaScript编程中的Promise使用方法_node.js

异步? 我在很多地方都看到过异步(Asynchronous)这个词,但在我还不是很理解这个概念的时候,却发现自己常常会被当做"已经很清楚"(* ̄? ̄). 如果你也有类似的情况,没关系,搜索一下这个词,就可以得到大致的说明.在这里,我会对JavaScript的异步做一点额外解释. 看一下这段代码: var start = new Date(); setTimeout(function(){ var end = new Date(); console.log("Time elap

javascript学习指南之回调问题_基础知识

回调地狱 对 JavaScript 程序员来说,处理回调是家常,但是处理层次过深的回调就没有那么美好了,下面的示例代码片段用了三层回调,再补脑一下更多层的场景,简直是酸爽,这就是传说中的回调地狱. getDirectories(function(dirs) { getFiles(dirs[0], function(files) { getContent(files[0], function(file, content) { console.log('filename:', file); cons

Angular中的Promise对象($q介绍)

 这篇文章主要介绍了Angular中的Promise对象($q介绍),本文讲解了Promise模式.Q Promise的基本用法.AngularJs中的$q.defferd等内容,需要的朋友可以参考下     在用JQuery的时候就知道 promise 是 Js异步编程模式的一种模式,但是不是很明白他跟JQuery的deferred对象有什么区别.随着公司项目的进行,要跟后台接数据了,所以决定搞定它. Promise Promise是一种模式,以同步操作的流程形式来操作异步事件,避免了层层嵌套

NodeJS中利用Promise来封装异步函数_node.js

 在写Node.js的过程中,连续的IO操作可能会导致"金字塔噩梦",回调函数的多重嵌套让代码变的难以维护,利用CommonJs的Promise来封装异步函数,使用统一的链式API来摆脱多重回调的噩梦. Node.js提供的非阻塞IO模型允许我们利用回调函数的方式处理IO操作,但是当需要连续的IO操作时,你的回调函数会多重嵌套,代码很不美观,而且不易维护,而且可能会有许多错误处理的重复代码,也就是所谓的"Pyramid of Doom". 复制代码 代码如下: st

js Promise异步编程示例

Promise 是JavaScript中的一种异步编程范式, 一个 Promise 对象表示一个即将完成但还未完成的操作. 鉴于JavaScript中异步和回调的编程风格, Promise 模式可以有效地避免『Callback Hell』. Promise 最初有 q 和 bluebird 等实现,在ES2015(ES6)提出后Promise已经进入标准,Node.js已经开始支持ES6的很多特性,包括Promise. 初始化 传入一个回调函数即可初始化一个Promise对象 padmin :

AngularJS 中的Promise --- $q服务详解_AngularJS

先说说什么是Promise,什么是$q吧.Promise是一种异步处理模式,有很多的实现方式,比如著名的Kris Kwal's Q还有JQuery的Deffered. 什么是Promise 以前了解过Ajax的都能体会到回调的痛苦,同步的代码很容易调试,但是异步回调的代码,会让开发者陷入泥潭,无法跟踪,比如: funA(arg1,arg2,function(){ funcB(arg1,arg2,function(){ funcC(arg1,arg2,function(){ xxxx.... })