小编Don*_*tch的帖子

javascript Promise API是否比它需要的更复杂?

我想我终于在大多数情况下都围绕着javascript/ES6 Promises.这并不容易!但是有些东西让我对这个设计感到困惑.

为什么Promise构造函数会进行回调?鉴于立即调用回调,调用者不能只执行该代码,从而避免一个不必要的心灵弯曲"不要打电话给我,我会打电话给你"?

以下是我所认为的Promise使用的原型示例,复制自Jake Archibald的Javascript Promises教程http://www.html5rocks.com/en/tutorials/es6/promises/#toc-promisifying-xmlhttprequest,并删除了注释.

它是XMLHttpRequest GET请求的基于Promise的包装器:

function get(url) {
  return new Promise(function(resolve, reject) {
    var req = new XMLHttpRequest();
    req.open('GET', url);
    req.onload = function() {
      if (req.status == 200) {
        resolve(req.response);
      }
      else {
        reject(Error(req.statusText));
      }
    };
    req.onerror = function() {
      reject(Error("Network Error"));
    };
    req.send();
  });
}
Run Code Online (Sandbox Code Playgroud)

对我来说,上面的代码将更容易理解,如果它被重写如下,使用我正在想象的一种非常不同的承诺,具有无参数构造函数和解析/拒绝方法:

function get(url) {
  var promise = new MyEasierToUnderstandPromise();
  var req = new XMLHttpRequest();
  req.open('GET', url);
  req.onload = function() {
    if (req.status == 200) {
      promise.resolve(req.response);
    }
    else { …
Run Code Online (Sandbox Code Playgroud)

javascript promise es6-promise

5
推荐指数
2
解决办法
208
查看次数

在javascript中可以阻止已失效的侦听器吗?

我的问题是" javascript中是否可以阻止失效的侦听器问题?" 但显然"问题"这个词会导致问题.

维基百科页面说,失败的监听器问题可以通过持有对观察者的弱引用的主题来解决.我之前在Java中已经实现了它并且它运行良好,我认为我将在Javascript中实现它,但现在我不知道如何.javascript甚至有弱引用吗?我看到有WeakSetWeakMap具有在其名称中的"弱",但他们似乎并没有被这个有帮助,据我所看到的.

这是一个jsfiddle,显示了问题的典型案例.

html:

<div id="theCurrentValueDiv">current value: false</div>
<button id="thePlusButton">+</button>
Run Code Online (Sandbox Code Playgroud)

javascript:

'use strict';
console.log("starting");
let createListenableValue = function(initialValue) {
  let value = initialValue;
  let listeners = [];
  return {
    // Get the current value.
    get: function() {
      return value;
    },
    // Set the value to newValue, and call listener()
    // for each listener that has been added using addListener().
    set: function(newValue) {
      value = newValue;
      for (let listener …
Run Code Online (Sandbox Code Playgroud)

javascript dom garbage-collection weak-references observer-pattern

5
推荐指数
1
解决办法
268
查看次数

为什么 javac -source 1.5 允许在接口方法上使用 @Override?

如果我理解正确的话,这里是一些在 1.5 下非法的示例 java 代码(因为@Override在 java 1.6 之前不能用于重写接口方法):

public class A { 
  public static interface MyInterface { 
    public void myInterfaceMethod();
  }
  public static class MyClass implements MyInterface { 
    @Override public void myInterfaceMethod() {}
  }
} 
Run Code Online (Sandbox Code Playgroud)

我想在我的源代码中找到所有此类 1.5 不兼容性,因此我在我的 ubuntu Linux 机器上安装了一个支持 java1.5 的编译器:

sudo apt install openjdk-8-jdk
JAVAROOT=/usr/lib/jvm/java-1.8.0-openjdk-amd64
${JAVAROOT}/bin/javac -version
# javac 1.8.0_232
Run Code Online (Sandbox Code Playgroud)

并编译了上面的java源代码:

${JAVAROOT}/bin/javac -source 1.5 -Xlint:all -Xlint:-options A.java
Run Code Online (Sandbox Code Playgroud)

我预计上面的java代码会被拒绝。但尽管在 1.5 下存在非法行为,但它显然编译成功了。

这是怎么回事?我是否误解了 1.5 规则@Override?或者我误解了-source 1.5应该做什么?

FWIW,我注意到这-source 1.4确实给出了预期的错误:

${JAVAROOT}/bin/javac -source …
Run Code Online (Sandbox Code Playgroud)

java java-5 java-6

5
推荐指数
1
解决办法
177
查看次数

神奇的静力学:相似的结构,有趣的非显而易见的用途?

C++11 引入了线程安全的局部静态初始化,又名“神奇静态”:局部静态变量初始化在 C++11 中是线程安全的吗?

规范特别指出:

如果在初始化变量时控制同时进入声明,则并发执行应等待初始化完成。

所以这里有一个隐式的互斥锁。这非常有趣,而且似乎是一种异常现象——也就是说,我不知道 C++ 中内置了任何其他隐式互斥体(即不使用 std::mutex 之类的互斥体语义)。还有其他的吗,或者这在规范中是独一无二的?

我也很好奇是否可以利用 magic static 的隐式互斥体(或其他隐式互斥体,如果有的话)来实现其他同步原语。例如,我发现它们可以用来实现 std::call_once,因为:

std::call_once(onceflag, some_function);
Run Code Online (Sandbox Code Playgroud)

可以表示为:

static int dummy = (some_function(), 0);
Run Code Online (Sandbox Code Playgroud)

但请注意,魔术静态版本比 std::call_once 受到更多限制,因为使用 std::call_once 您可以重新初始化一次标志,因此每次程序执行多次使用该代码,而使用魔术静态,您实际上只能得到每次程序执行时使用一次。

这是我能想到的唯一一种不太明显的魔法静力学用途。

是否可以使用 magic static 的隐式互斥体来实现其他同步原语,例如通用 std::mutex 或其他有用的东西?

multithreading c++11

4
推荐指数
1
解决办法
1193
查看次数

是否可以实现std :: move-and-clear功能?

是否可以编写一个函数move_and_clear,以便对于任何STL容器:

do_something_with(move_and_clear(container));
Run Code Online (Sandbox Code Playgroud)

相当于:

do_something_with(std::move(container));
container.clear();
Run Code Online (Sandbox Code Playgroud)

这是我的第一次尝试,但是没有用.我认为我的类型是正确的(虽然它的生产版本可能会在一些std :: remove_reference中出现),并且它成功编译,但它失败或崩溃,因为在超出范围后访问临时.

template<class T>
T &&move_and_clear(T &t)
{
    T scratch;
    std::swap(scratch, t);
    return std::move(scratch);
}
Run Code Online (Sandbox Code Playgroud)

这是我的第二次尝试.这实际上有效,但它是一个预处理器宏,因此是邪恶的:

template<class T>
T &&move_and_clear_helper(T &t, T &&scratch)
{
    std::swap(scratch, t);
    return std::move(scratch);
}
#define move_and_clear(t) move_and_clear_helper(t, decltype(t)())
Run Code Online (Sandbox Code Playgroud)

我的第三次尝试是另一个也可以工作的宏,这次是使用lambda而不是命名的辅助函数.所以它比以前的宏更加独立,但可能不太可读,当然它仍然是邪恶的,因为它是一个宏:

#define move_and_clear(t) \
    [](decltype(t) &tparam, decltype(t) &&scratch){ \
        std::swap(scratch, tparam); \
        return std::move(scratch); \
    }(t, decltype(t)())
Run Code Online (Sandbox Code Playgroud)

这是一个包含我三次尝试的可编辑程序:

/*
    g++ --std=c++11 -W -Wall -g move_and_clear.cc -o move_and_clear1 -DWHICH=1
    g++ --std=c++11 -W -Wall -g move_and_clear.cc -o move_and_clear2 -DWHICH=2
    g++ --std=c++11 -W …
Run Code Online (Sandbox Code Playgroud)

c++ rvalue-reference move-semantics c++11

3
推荐指数
1
解决办法
916
查看次数

为什么 HTTP 请求标头“If-None-Match”这样称呼?

If-None-Match请求头字段的行为在RFC7232 的第 3.2 节中指定

我理解规范的这一部分,不需要解释。我不明白的是为什么标题被命名为“If-None-Match”。这对我来说和“Wherefore-Giraffe-Bathtub”一样有意义。

这个名字是否有理由,或者至少是一个体面的助记符,可以帮助我记住一周后的含义?

http http-headers

3
推荐指数
1
解决办法
622
查看次数

我如何回到kcachegrind的开头?

有时我运行kcachegrind,点击一会儿,点击关闭左侧面板的小'x'(哎呀!不知道如何取回它),点击更多,完全丢失,然后退出kcachegrind.

然后我再次在相同的输入文件上重新运行kcachegrind,希望重新开始,但相反,kcachegrind"帮助"记住我所处的破碎状态并让我回到那里,即完全丢失并且我有一个缺少的面板不知道怎么回来.

我该如何恢复?

  • Hitting Up,Up,Up ...并没有帮助我找到节点"main",因为我在一个循环中,并且main甚至不在当前的调用图中,因为我在一个线程中.
  • 文件 - >重新加载没有帮助.
  • 视图 - >布局 - >恢复到默认没有帮助.
  • 重命名输入文件没有帮助.
  • 删除并重新安装kcachegrind并没有帮助.

我该如何回到起点?也就是说,默认布局,默认节点,默认其他一切.

我在ubuntu 14.04上使用KCachegrind版本0.7.4kde.

kcachegrind

2
推荐指数
1
解决办法
319
查看次数

异步生成器在解决时产生承诺结果

假设我想同时获取 10 个 url,并在收到响应时对其进行处理(其顺序可能与它们在原始列表中出现的顺序不同)。忽略拒绝的可能性,一种方法是简单地为每个 Promise 附加一个“then”回调,然后等待它们全部使用完成Promise.all()

const fetch_promises = [
  fetch("https://cors-demo.glitch.me/allow-cors"),
  fetch("/"),
  fetch("."),
  fetch(""),
  fetch("https://enable-cors.org"),
  fetch("https://html5rocks-cors.s3-website-us-east-1.amazonaws.com/index.html"),
  fetch("https://api.github.com"),
  fetch("https://api.flickr.com/services/rest/"),
];
const processing_promises = [];
for (const fetch_promise of fetch_promises) {
  processing_promises.push(fetch_promise.then(response => {
    // Process response.  In this example, that means just
    // print it.
    console.log("got a response: ",response);
  }));
}
await Promise.all(processing_promises);
Run Code Online (Sandbox Code Playgroud)

切换到输出更清晰、更具确定性的示例:

const sleep = millis => new Promise(resolve=>setTimeout(resolve, millis));
const sleep_promises = [
    sleep(3000).then(()=>"slept 3000"),
    sleep(1000).then(()=>"slept 1000"),
    sleep(5000).then(()=>"slept 5000"),
    sleep(4000).then(()=>"slept 4000"),
    sleep(2000).then(()=>"slept 2000"),
];
const processing_promises …
Run Code Online (Sandbox Code Playgroud)

javascript generator fetch promise async-await

1
推荐指数
1
解决办法
1463
查看次数