GVKun编程网logo

提供Promise作为模块的输出是否是Node.js中用于初始化初始化的有效模式?

11

对于提供Promise作为模块的输出是否是Node.js中用于初始化初始化的有效模式?感兴趣的读者,本文将会是一篇不错的选择,并为您提供关于ArrayList初始化等效于数组初始化、c–复制初始化和直

对于提供Promise作为模块的输出是否是Node.js中用于初始化初始化的有效模式?感兴趣的读者,本文将会是一篇不错的选择,并为您提供关于ArrayList初始化等效于数组初始化、c – 复制初始化和直接初始化的混乱、c – 如何使用未初始化的数据有意初始化变量,以便valgrind将变量视为未初始化?、c – 没有用于初始化的匹配构造函数的有用信息。

本文目录一览:

提供Promise作为模块的输出是否是Node.js中用于初始化初始化的有效模式?

提供Promise作为模块的输出是否是Node.js中用于初始化初始化的有效模式?

我需要编写一些模块,一次加载数据,然后提供该数据的接口。我想异步加载数据。我的应用程序已经使用了Promise。是否由于需要模块而提供有效的模式/习惯?

示例模块:

var DB = require(''promise-based-db-module'');module.exports =  DB.fetch(''foo'')  .then(function(foo){    return {        getId: function(){return foo.id;},        getName: function(){return foo.name;}    };  });

用法示例:

require(''./myPromiseModule'').then(function(dataInterface){  // Use the data});

更新:

我已经使用了一段时间了,效果很好。我已经了解到的一件事(在已接受的答案中得到了暗示)是,缓存承诺本身以及在每次访问数据使用时都很好then。第一次访问数据时,代码将等待直到承诺被解决。的后续使用then将立即返回数据。例如

var cachedPromise = require(''./myPromiseModule'');cachedPromise.then(function(dataInterface){  // Use the data});...cachedPromise.then(function(dataInterface){  // Use the data again somewhere else.});

答案1

小编典典

对于一个模块来说,这似乎是一个完美的界面,该模块的任务是一次性读取某些数据。

数据是异步获取的,因此对此应有承诺。目标是只获取一次数据,然后让该模块使用的所有位置都可以访问该原始数据。一个诺言也很有效,因为它是一个记住其状态的一次性装置。

就我个人而言,我不确定为什么只可以直接访问属性时为什么需要getId()and getName()方法,但是两者都可以使用。

该接口的缺点是无法请求数据的新副本(从数据库中新加载)。

ArrayList初始化等效于数组初始化

ArrayList初始化等效于数组初始化

我知道您可以在实例化期间初始化数组,如下所示:

String[] names = new String[] {"Ryan", "Julie", "Bob"};

有没有办法用ArrayList做同样的事情?还是我必须单独添加内容array.add()

答案1

小编典典

Arrays.asList可以在这里提供帮助:

new ArrayList<Integer>(Arrays.asList(1,2,3,5,8,13,21));

c – 复制初始化和直接初始化的混乱

c – 复制初始化和直接初始化的混乱

考虑简单陈述(摘自 Is there a difference in C++ between copy initialization and direct initialization?):

A c2 = A();

This statement value-initializes a temporary and then copies that
value into c2 (Read 5.2.3/2 and 8.5/14). This of course will require a
non-explicit copy constructor (Read 8.5/14 and 12.3.1/3 and
13.3.1.3/1)

[注意上面的段落中的大胆句子] – >我的问题是为什么?

现在考虑这段代码:

class B {};
struct A 
{
  A(B const&) {}
  A(A const&) = delete;
  //A(A const&); //delete above statement and uncomment this statement,//and everything works,even though there in no body of copy constructor Oo
};

A a2 = B();    //error since there is no copy constructor oO

为什么复制初始化需要复制构造函数的存在,即使它在某些时候不需要,如上面的代码所示

请再请一件事:

While direct initialization has all constructors available to call,
and in addition can do any implicit conversion it needs to match up
argument types,copy initialization can just set up one implicit
conversion sequence
.

[注意以下段落中的粗体]

这是否意味着直接初始化可以访问所有构造函数并且可以执行隐式转换序列,而复制初始化所有可以做的是执行隐式转换序列? .我的意思是,直接初始化中的隐式转换与复制初始化中的隐式转换序列不同?

解决方法

评估规则

A a1 = B();   // (1) copy-initialization
A a2 = {B()}; // (2) copy-initialization
A a3{B()};    // (3) direct-initialization

来自[dcl.init]/17:

— If the initializer is a (non-parenthesized) braced-init-list,the object or reference is list-initialized (8.5.4).
— […]
— If the destination type is a (possibly cv-qualified) class type:

  • If the initialization is direct-initialization,or if it is copy-initialization where the cv-unqualified
    version of the source type is the same class as,or a derived class of,the class of the destination,
    constructors are considered. […]
  • Otherwise (i.e.,for the remaining copy-initialization cases),user-defined conversion sequences
    that can convert from the source type to the destination type or (when a conversion function
    is used) to a derived class thereof are enumerated as described in 13.3.1.4,and the best one is
    chosen through overload resolution (13.3). […] The result of the call (which is the temporary for the constructor case) is then used to direct-initialize,according to the rules above,
    the object that is the destination of the copy-initialization. In certain cases,an implementation
    is permitted to eliminate the copying inherent in this direct-initialization by constructing the
    intermediate result directly into the object being initialized; see 12.2,12.8.
  • @H_301_83@

对于a2和a3,初始化程序是braced-init-list,所以我们只进行列表初始化.这最终称为B const&构造函数.

对于a1,第一个子项不适用 – 因为源类型(B)不是目标类型(A)的相同或派生类.因此,我们进入第二个子项目,涉及考虑转换函数.有一个(A(B const&))所以我们有效地重写了表达式

A a1_new{A{B{}}};

现在通常,这个额外的副本将被省略.但是你明确禁止它,所以代码无法编译.

至于为何分化?我不知道.似乎复制初始化应该只是直接初始化的语法糖.毕竟,在大多数情况下,它是……

c – 如何使用未初始化的数据有意初始化变量,以便valgrind将变量视为未初始化?

c – 如何使用未初始化的数据有意初始化变量,以便valgrind将变量视为未初始化?

我的代码中有一个垃圾数据缓冲区,我将其传递给写入它的函数.我不需要这个垃圾缓冲区的数据.由于我需要在多个地方使用这样的垃圾数据缓冲区,但从不从它们读取,我到处使用相同的垃圾缓冲区.

当一些虚假代码从垃圾数据缓冲区中读取时,这将是致命的,或者,例如,当我使用垃圾数据缓冲区时,我应该使用适当的专用缓冲区.

理想情况下,我想让伪代码快速崩溃,因此我在调用写入函数后对数据进行加扰,因此没有人可以使用(并依赖)垃圾数据.

现在我有了一个想法,我可以将未初始化的数据复制到垃圾数据而不是加扰它,因此valgrind可以从垃圾缓冲区中找到所有读取.

我当前的解决方案是new []一些字节,并将未初始化的内容复制到垃圾缓冲区,然后删除[]未初始化的数据.由于未初始化的数据在大多数情况下是0(不幸的是),因此我将其与模式进行异或.对于这么简单的事情,这一切似乎都很复杂.

有没有人想出更好的解决方案?

解决方法

Valgrind(和memcheck)有一个 C API!

你可以这样做:

#include <memcheck.h>

// ....

VALGRIND_MAKE_MEM_UNDEFINED(trash_buffer,trash_length);

如果您希望valgrind将数据视为不可访问而不仅仅是单元化,您还可以使用VALGRIND_MAKE_MEM_NOACCESS.

在valgrind外部运行时,这将只有很少的运行时开销.即使不在valgrind中运行,你复制内容的方法也可能很昂贵.

c – 没有用于初始化的匹配构造函数

c – 没有用于初始化的匹配构造函数

我在StackOverflow上看过类似的问题,但似乎没有一个适用于我.

这是我的代码:

Option.cpp

#include "Option.h"

Option::Option(string valueName,string description,OptionType type){
    this->valueName = valueName;
    this->description = description;
    this->type = type;
};

Option.h

#include <iostream>
using namespace std;

enum OptionType { FLAG,required,norMAL };
class Option {
    string valueName,description,value;
    OptionType type;
public:
    Option(string valueName,OptionType type);
    void setValue(string value) {
        this->value = value;
    };
    string getValueName() {
        return this->valueName;
    };
    string getDescription() {
        return this->description;
    };
    OptionType getType() {
        return this->type;
    };
};

Options.cpp

#include "Options.h"
using namespace std;

Options::Options(int _argc,const char * _argv[]) : argv(_argv) {
    this->argc = _argc;
}

Options::~Options() {
    options.~unordered_map();
}

void Options::printHelp() {
    for (auto &i : options) {
        cout << i.first << '\t' << i.second.getDescription() << '\n';
    }
}

void Options::addFlag(string flagName,string description) {

}

void Options::addOption(string optionName,string valueName,OptionType type) {
    Option option(valueName,type);
    options[optionName]=option;
}

void Options::addOptionAlias(string aliasName,string optionName) {

}

Options.h

#include <iostream>
#include <unordered_map>
#include "Option.h"

using namespace std;

class Options {
    unordered_map<string,Option> options;
    int argc;
    const char ** argv;

public:
    Options(int argc,const char * argv[]);
    ~Options();
    void parse();
    void addOption(string optionName,OptionType type);
    void addFlag(string flagName,string description);
    void addOptionAlias(string aliasName,string optionName);
    void getoption(string optionName);
    void printHelp();


};

它位于选项选项(valueName,type)行的options.cpp中;错误似乎源于此,但对于我的生活,我无法弄清楚为什么.据我所知,Option中的构造函数采用了正确的类型.

解决方法

问题实际上在下一行:

options[optionName]=option;

首先调用map中的operator [],搜索给定的键并返回相关的值.如果未找到密钥,则会插入连接到该密钥的默认初始化值.然后,此值是使用您的选项分配的副本.

你看到了问题吗?您的Option类没有默认构造函数,因此无法进行默认初始化!仔细阅读您的错误消息,肯定是在讨论默认构造函数,而不是您正在查看的构造函数.

你有几个解决方案.最简单的方法是为您的类编写默认构造函数.

另一种方法是永远不要在map中使用operator [],这样就不需要默认的构造函数了.如果这是你想要做的,插入你写的项目:

options.insert(std::make_pair(optionName,option));

最后,如果您使用的是C 11(或更高版本)以及兼容性足够的编译器,您甚至可以直接将对象构建到容器中:零复制开销,您甚至不需要复制构造函数!

options.emplace(std::piecewise_construct,std::forward_as_tuple(optionName),std::forward_as_tuple(valueName,type));

今天关于提供Promise作为模块的输出是否是Node.js中用于初始化初始化的有效模式?的讲解已经结束,谢谢您的阅读,如果想了解更多关于ArrayList初始化等效于数组初始化、c – 复制初始化和直接初始化的混乱、c – 如何使用未初始化的数据有意初始化变量,以便valgrind将变量视为未初始化?、c – 没有用于初始化的匹配构造函数的相关知识,请在本站搜索。

本文标签: