【问题标题】:then of promise not waiting for result to return然后承诺不等待结果返回
【发布时间】:2017-02-03 18:02:19
【问题描述】:

以下是node.js中使用promise的函数。

exports.getDetailsByUserId = function(req,res) {
     getUserDetails(req, res) // function to get user details
    .then(function (Details) {
        var allpromises = Details.map(getStatus); //get and update the status of user
        return allpromises
    })
    .then(function (promises) {
        var orderresult =[];
        Q.allSettled(promises)
        .then(function (allpromises) {
            orderresult.push(allpromises);
        })
        return orderresult;
    })
    .then(function (result) {
        getUserDetails(req, res)//again calling get user details so that i will get modified result
       .then(function (data) {
            res.json({                             
                "User" : data
            })
        })
    })
    .catch(function (error) {
        console.log(error);
        res.status(200).json({
            "Message": error
        })
    })
}

var getStatus = function (data,req) {
    var deferred = Q.defer();
        requestify.post('http://example.com', {
            "data": [{ "Number": No }]
        })
    .then(function (response) {
            response.getBody();
            response.body;
            var Status = JSON.parse(response.body);
          var Details = { "_id": data._id, "Status": Status.status[0] };
          return OrderDetails;
    })
    .then(function (DetailsData){
        var req = { body : { Details :DetailsData} };
       updateDetails(req).then(function (data) { 
          deferred.resolve;
        })
    })
   .catch(function (error) {                     
        deferred.resolve(error);
   });    
    return deferred.promise;
}

getUserDetails 函数第一次获取用户的详细信息,然后getStatus 调用另一个 API 并更新相关的用户状态。至此,一切正常。

我需要再次调用getUserDetails 以获取更新结果,但它没有给出更新结果。也许它在更新状态之前被调用?代码可能有什么问题,以便在Q.all 之后执行?

谢谢。

【问题讨论】:

  • orderresult 有什么意义?将数组包装在数组中?
  • 您不需要拨打getUserDetails 两次。只是更新它们,你不知道它们已经是什么了吗?
  • orderresult 是一个 promise 数组。我想让更新的结果显示在网格中
  • 不,不是。这很可能是你的问题。
  • 在第二次调用 getUserDetails(req, res) 之前,您无需等待 Q.allSettled(promises) 完成。另一个异步 javascript 问题...

标签: node.js promise q


【解决方案1】:
var orderresult =[];
Q.allSettled(promises)
.then(function (allpromises) {
    orderresult.push(allpromises);
})
return orderresult;

你爱上了经典的mutation in asynchronous callback 问题。 then 回调是异步的,orderresult 在返回时不会包含 allpromises 数组。要让某些东西等待承诺,你必须return它。

无论如何,您都应该将代码简化为

getUserDetails(req, res)
.then(function (details) {
    var allpromises = details.map(getStatus);
    return Q.allSettled(allpromises); // just call it here already and return a promise
})
.then(function (allpromiseresults) {
    var orderresult = [allpromiseresults]; // not sure what this is good for
    return orderresult;
})
.then(function (result) { // given that you don't use the `result` anyway
    return getUserDetails(req, res);
}).then(function (data) {
    res.json({                             
        "User" : data
    })
}, function (error) {
    console.log(error);
    res.status(200).json({
        "Message": error
    })
});

在getStatus 中,您应该避免使用deferred antipattern:

function getStatus(data,req) {
    return requestify.post('http://example.com', {
        "data": [{ "Number": No }]
    })
    .then(function (response) {
        response.getBody(); // ???
        var status = JSON.parse(response.body);
        var details = { "_id": data._id, "Status": Status.status[0] };
        // no `OrderDetails`, no `DetailsData`

        var req = {body: {Details: details}};
        return updateDetails(req) // probably "getStatus" should be called "updateStatus"
    });
}

【讨论】:

  • 感谢您宝贵的时间和广泛的回答,但这仍然会在 Q.allSettled(allpromises) 返回并给出未修改的结果之前执行对“getUserDetails”的第二次调用。现在我尝试调用 updateDetails,毕竟 Q.allSettled(allpromises) 希望它能工作而不是调用 getStatus。
  • @sam 如果是这样,您可能在某处忘记了return。我的代码当然不会在allSettled returns 之后调用第二个getUserDetails,它甚至会等到promise fulfills。是什么让你觉得它发生在“之前”? updateDetails 中可能存在错误(您尚未显示)。确保它返回的承诺确实有效。
  • 已经修改了上面的代码来处理 then.it 现在可以工作了。
  • @sam 你不应该编辑我的答案(除了明显的错误或改进),而是发表评论。鉴于your suggestion 确实涉及deferred,您似乎没有使用我的答案-您根本不需要任何延期!请阅读反模式上的链接。
猜你喜欢
  • 2019-10-20
  • 1970-01-01
  • 2019-06-30
  • 1970-01-01
  • 1970-01-01
  • 2018-08-17
  • 2020-12-18
  • 2017-06-24
  • 2022-11-16
相关资源
最近更新 更多