Nodejs中promise(Q)的使用方法

Nodejs中promise(Q)的使用方法

最近写的一段代码中因为多次需要依靠回调函数的返回值进行下一次回调,代码看起来十分的不好看,就想着去借助promise(Q)去优化一下代码,但是看了文档,还是一头雾水啊,例如下面的代码:

request.get(uri,function(err,res,body){
    request.post({
        uri: uri1,
        form: body
    },function(err,res,body1){
        request.post({
            uri: uri2,
            form: body1
        },function(err,res,body2){
            //do something
        })
    })
})

如果用Q来写的话,该怎么写啊?


8 回复

Node.js 中 Promise (Q) 的使用方法

最近写的一段代码中因为多次需要依靠回调函数的返回值进行下一次回调,代码看起来十分的不好看,就想着去借助 Promise 来优化一下代码。Promise 可以帮助我们更好地管理异步操作,避免回调地狱(Callback Hell)。这里以 Q 库为例,展示如何使用 Promise 来简化上述代码。

示例代码

首先,确保你已经安装了 q 库。如果没有安装,可以使用以下命令安装:

npm install q

接下来,我们将使用 Q 库来重写上面的代码。

const Q = require('q');
const request = require('request');

// 将 request.get 包装成返回 Promise 的函数
function get(uri) {
    const deferred = Q.defer();
    request.get(uri, (err, res, body) => {
        if (err) {
            deferred.reject(err);
        } else {
            deferred.resolve(body);
        }
    });
    return deferred.promise;
}

// 将 request.post 包装成返回 Promise 的函数
function post(options) {
    const deferred = Q.defer();
    request.post(options, (err, res, body) => {
        if (err) {
            deferred.reject(err);
        } else {
            deferred.resolve(body);
        }
    });
    return deferred.promise;
}

// 使用 Promise 链式调用
get(uri)
    .then(body => post({ uri: uri1, form: body }))
    .then(body1 => post({ uri: uri2, form: body1 }))
    .then(body2 => {
        // do something
        console.log(body2);
    })
    .catch(err => {
        console.error('Error:', err);
    });

解释

  1. 创建包装函数:我们为 request.getrequest.post 创建了两个函数 getpost,这两个函数都返回一个 Promise 对象。

    • get(uri) 函数接收一个 URI,发起一个 GET 请求,并根据请求结果解析或拒绝 Promise
    • post(options) 函数接收一个选项对象,发起一个 POST 请求,并根据请求结果解析或拒绝 Promise
  2. 链式调用:通过 .then() 方法,我们可以链式地处理每个异步操作的结果。每个 .then() 方法接收前一个 .then() 方法返回的值,并将其作为下一个 .then() 方法的输入。

  3. 错误处理:使用 .catch() 方法捕获任何错误,避免程序崩溃。

通过这种方式,代码变得更加清晰和易于维护。希望这能帮助你理解如何使用 Promise 来优化你的 Node.js 代码。


找到了个很不错的示例

看到Q就喷一次,比他好的太多了。推荐bluebird,API简洁,功能强大,尤其是它的promisifyAll方法 楼主的方法用bluebird的示例:

var Promise = require('bluebird')
var request = require('request')
Promise.promisifyAll(request)

//开始飞吧 request.getAsync(url).spread(function(res, body1){ return request.postAsync({uri: uri1, form: body1}) }).spread(function(res, body2){ return request.postAsync({uri: uri2, form: body2}) }).spread(function(res, body3){ //code with results }).error(function(){ //handle error here })

呃,怎么都不喜欢Q么?

最近刚刚看了下Q的文档,尝试一下,有错误请指正。

var Q = require('q');
var request = require('request');

var r = function () { var wrap = function (result) { // nfapply 包装的promise会将传递 [res, body] return result[1]; }; // 这里返回一个包装好的promise return Q.nfapply(request, arguments).then(wrap); };

var promise = r({uri: uri}) .then(function (body) { return r({method: ‘POST’, uri: uri1, form: body}); }) .then(function (body1) { return r({method: ‘POST’, uri: uri2, form: body1}); });

// 接下来 promise.then(function (body2) { // do something }, function (err) { // handle err });

bluebird不错,学习了。

q很好,一直用,直到发现了co yield,推荐你换换,不能更简单了 自豪地采用 CNodeJS ionic

使用 Q 库可以简化你的异步代码,并使代码更加可读。下面是如何将你的代码重构为使用 Q 的示例:

首先,确保你已经安装了 q 库:

npm install q

接下来,你可以使用 Q 库的 defer 方法创建一个 deferred 对象,然后通过调用 resolvereject 方法来控制 promise 的状态。

下面是你的代码使用 Q 重构后的示例:

const Q = require('q');
const request = require('request');

function requestGet(uri) {
    let deferred = Q.defer();
    request.get(uri, (err, res, body) => {
        if (err) {
            deferred.reject(err);
        } else {
            deferred.resolve(body);
        }
    });
    return deferred.promise;
}

function requestPost(uri, form) {
    let deferred = Q.defer();
    request.post({uri: uri, form: form}, (err, res, body) => {
        if (err) {
            deferred.reject(err);
        } else {
            deferred.resolve(body);
        }
    });
    return deferred.promise;
}

requestGet(uri)
    .then((body) => requestPost(uri1, {form: body}))
    .then((body1) => requestPost(uri2, {form: body1}))
    .then((body2) => {
        // do something with body2
    })
    .catch((error) => {
        console.error(error);
    });

在这个示例中,我们定义了两个函数 requestGetrequestPost,它们都返回一个 promise。这些 promise 在请求成功时被解析(resolve),在发生错误时被拒绝(reject)。最后,我们使用 .then() 方法链接这些 promise,这样可以保证每个操作都在前一个操作成功后执行。如果有任何步骤失败,.catch() 方法会捕获错误并处理它。这样,代码结构更清晰,逻辑也更容易理解。

回到顶部