NodeJS中的一系列承诺延期承诺? [英] Promise from an array of promises in NodeJS Deferred?

查看:106
本文介绍了NodeJS中的一系列承诺延期承诺?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个模块,输出一组关于应用程序运行状况的指标,例如后台队列长度,服务依赖性响应时间等。这是Node JS使用延期

I want to make a module that outputs a set of metrics about the health of my application, such as background queue lengths, response time to service dependencies etc. This is Node JS using Deferred:

var metrics = {
    queueLength: function(def) {
        // .. Do some stuff to resolve the queue length ..
        def.resolve(45); // Example
    }
    // ... more metrics
}
for (i in metrics) {
    def = deferred();
    metrics[i](def);
    promiselist.push(def.promise);
    def.promise(function(result) {
        metrics[i] = result;
    }
}
return deferred(promiselist)(function(result) {
    console.log('All metrics loaded', result, metrics);
});

这会产生输出

Metrics loaded [ [Function] ]  { queueLength: [Function] }

当我预料到:

Metrics loaded [ 45 ]  { queueLength: 45 }

我想我正在做两件事情错了,但不知道如何正确地纠正它们:

I think I'm doing two things wrong but don't know how to correct them 'properly':


  • 返回延迟([数组]承诺])(团体承诺)想法似乎不起作用

  • 我刚刚意识到 def 正在重复使用每次迭代,所以如果我有多个指标,它可能只跟踪最后一个。

  • The return deferred([array of promises])(group promise) idea doesn't seem to work
  • I've just realised def is getting reused on each iteration so if I had multiple metrics it would probably only track the last one.

推荐答案


metrics[i] = result;


这是一个坏主意。你不应该破坏 metrics 对象,它的属性应该是并保持功能。如果你想要一个包含结果的对象,那么建立一个新的。

That's a bad idea. You shouldn't destroy the metrics object, it's properties are supposed to be and to stay functions. If you want an object with the results, build a new one.


延迟的返回([数组的承诺])(组承诺)想法似乎不起作用

The return deferred([array of promises])(group promise) idea doesn't seem to work

来自文档和代码,你可以看到该库不支持数组作为参数。您需要使用 apply

From the docs and the code you can see that the library does not support arrays as arguments. You will need to use apply:

deferred.apply(null, promiselist)




我刚刚意识到def会在每次迭代中重复使用,所以如果我有多个指标它可能只跟踪最后一个。

I've just realised def is getting reused on each iteration so if I had multiple metrics it would probably only track the last one.

不,它没有被重用,你在每个循环转换时创建一个新的延迟对象。但你确实忘记了 var 关键字使变量成为本地。

No, it's not getting reused, you're creating a new deferred object each loop turn. You did however forget the var keyword to make the variable local.

i 变量 - 它不在每个promise回调的闭包范围内,这意味着当回调被解析时,变量将已经具有来自最后一个循环回合的值。检查循环内的JavaScript闭包 - 简单的实际示例

There also is a problem with the i variable - it is not in the closure scope of each promise callback, which means that when the callbacks are resolved then the variable will already have the value from the last loop turn. Check JavaScript closure inside loops – simple practical example.

一个小的设计缺陷是 metrics 方法确实将延迟作为他们将解决的参数。如果他们没有采取任何争论,并为他们自己创造(和管理)的结果返回承诺会更好。

A small design flaw is that the metrics methods do take a deferred as an argument which they will resolve. It would be better if they did take no argument, and return a promise for their result which they create (and manage) on their own.

var metrics = {
    queueLength: function() {
        var def = deferred();
            // .. Do some stuff to resolve the queue length ..
            def.resolve(45); // Example
        return def.promise;
    }
    // ... more metrics
};

var results = {},
    promiselist = [];
for (var p in metrics) {
    promiselist.push( metrics[p]().aside( function(_p) {
        return function(result) {
            results[_p] = result;
        };
    }(p) ) );
}
return deferred.apply(null, promiselist).then(function(resultArr) {
    console.log('All metrics loaded', resultArr, results);
    return results;
});

这篇关于NodeJS中的一系列承诺延期承诺?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆