我尝试将 rxjs 与 babeljs 结合使用来创建一个异步生成器函数,该函数在next被调用时产生,在error被调用时抛出,并在complete被调用时完成。我遇到的问题是我无法从回调中屈服。
我可以await承诺处理返回/抛出要求。
async function *getData( observable ) {
await new Promise( ( resolve, reject ) => {
observable.subscribe( {
next( data ) {
yield data; // can't yield here
},
error( err ) {
reject( err );
},
complete() {
resolve();
}
} );
} );
}
( async function example() {
for await( const data of getData( foo ) ) {
console.log( 'data received' );
}
console.log( …Run Code Online (Sandbox Code Playgroud) 鉴于这两个类
class Foo{
f1;
get f2(){
return "a";
}
}
class Bar extends Foo {
b1;
get b2(){
return "a";
}
}
let bar = new Bar();
Run Code Online (Sandbox Code Playgroud)
什么代码会从bar实例中获取此属性列表?['f1', 'f2', 'b1', 'b2']
更新
这应该是@Marc C答案的一部分:
使用装饰器我可以轻松地将不可枚举的属性转换为可枚举的属性:
class Bar extends Foo {
@enumerable()
get b2(){
return "a";
}
}
Run Code Online (Sandbox Code Playgroud)
这是装饰源:
function enumerable() {
return function(target, key, descriptor) {
if (descriptor) {
descriptor.enumerable = true;
}
};
}
Run Code Online (Sandbox Code Playgroud)
ES6具有返回迭代器的生成器:
function* range(n) {
for (let i = 0; i < n; ++i) {
yield i;
}
}
for (let x of range(10)) {
console.log(x);
}
Run Code Online (Sandbox Code Playgroud)
有一个异步函数的提议,它返回Promises:
async function f(x) {
let y = await g(x);
return y * y;
}
f(2).then(y => {
console.log(y);
});
Run Code Online (Sandbox Code Playgroud)
那么如果我将两者结合起来会发生什么,就像这样:
async function* ag(n) {
for (let i = 0; i < n; ++i) {
yield i;
}
}
Run Code Online (Sandbox Code Playgroud)
它返回了什么?是Promise<Iterator<Item>>吗?Iterator<Promise<Item>>?别的什么?我该如何食用?我想应该有一个相应的for循环,什么会异步迭代它的结果,如:
for (await let x …Run Code Online (Sandbox Code Playgroud) javascript generator async-await ecmascript-6 ecmascript-next
我有以下设置:
{
"babel-core": "~5.8.25",
"babel-eslint": "^4.1.3",
"babel-loader": "~5.3.2",
"babel-polyfill": "^6.2.0",
"eslint": "^1.7.3",
"eslint-config-airbnb": "^0.1.0",
"eslint-loader": "~1.1.0",
"eslint-plugin-angular": "~0.12.0",
// ...
}
Run Code Online (Sandbox Code Playgroud)
的WebPack:
module: {
preLoaders: [{ test: /\.js$/, exclude: /node_modules/, loader: 'eslint-loader'}],
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loaders: ['ng-annotate', 'babel-loader?plugins[]=transform-decorators-legacy'],
}
]
}
Run Code Online (Sandbox Code Playgroud)
但是我收到以下错误:
TypeError: The plugin "transform-decorators-legacy" didn't export a Plugin instance
Run Code Online (Sandbox Code Playgroud)
有谁知道我在这里做错了什么?
UPDATE
我已经升级到Babel 6,现在有以下设置:
{
"babel-core": "^6.0.0",
"babel-eslint": "^4.1.3",
"babel-loader": "^6.0.0",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-polyfill": "^6.2.0",
"babel-preset-es2015": "^6.0.0",
"babel-preset-stage-0": "^6.5.0",
"eslint": "^1.10.0",
"eslint-config-airbnb": "^4.0.0",
"eslint-loader": "^1.2.0", …Run Code Online (Sandbox Code Playgroud) 例如,为什么下面的函数需要"async"..是不是使用等待特定的足够的编译器来解析代码而没有歧义?
# Why do we need async here
async function foo() {
var user = await getUser(user_id);
console.log(user);
}
Run Code Online (Sandbox Code Playgroud)
是出于向后兼容的原因吗?(我想不出任何在标准Javascript中使用await键盘的代码..)?
是否主要是为了清楚地表明此函数使用新的async关键字?谢谢
我只想等待一个进程完成,不想让函数异步.
请参阅以下代码.
我不得不使getUserList异步,因为函数中有一个await关键字.因此,我还必须编写"await UsersService.getUserList"来执行该方法,并且我必须使父函数异步.那不是我想要做的.
import xr from 'xr' //a package for http requests
class UsersService {
static async getUserList() {
const res = await xr.get('http://localhost/api/users')
return res.data
}
}
export default UsersService
Run Code Online (Sandbox Code Playgroud)
import UsersService from './UsersService'
class SomeClass {
async someFunction() { //async again!!
const users = await UsersService.getUserList() //await again!!
}
}
Run Code Online (Sandbox Code Playgroud) 我有2个非常相关的问题.一个实际的,与我所遇到的真正问题有关,还有一个理论问题.让我从后者开始:
一般来说,在回调或承诺中产生收益并没有多大意义.问题(以及其他问题)是在多个产量之间可能存在竞争,无法判断发电机何时结束等.
function* this_is_nonsense() {
setTimeout(() => { yield 'a'; }, 500);
setTimeout(() => { yield 'b'; }, 500);
return 'c';
}
Run Code Online (Sandbox Code Playgroud)
当使用async/await时,这些问题似乎实际上已经消失了
function timeout(ns) {
return new Promise((resolve) => setTimeout(resolve, ns));
}
async function* this_could_maybe_make_sense() {
// now stuff is sequenced instead of racing
await timeout(500);
yield 'a';
await timeout(500);
yield 'b';
return 'c';
}
Run Code Online (Sandbox Code Playgroud)
我假设目前没有这样的事情(如果错误请纠正我!).所以我的第一个问题是,使用async/await生成器是否存在概念性问题?如果没有,是否在任何路线图上?似乎实现需要的不仅仅是将两个功能混合在一起.
这是我所拥有的真实代码问题的人为版本.
想象一下编写一个遍历维基百科的函数,从一些任意页面开始并反复跟随链接(无论如何 - 可以是深度优先,广度优先还是其他东西).假设我们可以异步爬行维基百科页面以获取链接页面.就像是:
async function traverseWikipedia(startLink) {
const visited = {};
const result = [];
function …Run Code Online (Sandbox Code Playgroud) javascript generator async-await ecmascript-6 ecmascript-next
如何使用ES7类装饰器覆盖构造函数?
例如,我想要有类似的东西:
@injectAttributes({ foo: 42 })
class Bar {
constructor() {
console.log(this.foo);
}
}
Run Code Online (Sandbox Code Playgroud)
当injectAttributes它们被创建之前将装饰属性注入到新的实例:
> bar = new Bar();
42
> bar.foo
42
Run Code Online (Sandbox Code Playgroud)
显而易见的解决方案 - 使用不同的构造函数:
function overrideConstructor(cls, attrs) {
Object.assign(this, attrs);
cls.call(this);
}
Run Code Online (Sandbox Code Playgroud)
不起作用,因为创建的对象将是新构造函数的实例,而不是原始类型:
> bar = new overrideConstructor(Bar, {foo: 42})
42
> bar
[overrideConstructor {}]
> bar instanceof Bar
false
Run Code Online (Sandbox Code Playgroud) 通过将其原型设置为Array.prototype:我可以轻松地使普通对象看起来像一个数组:
const obj = {};
Reflect.setPrototypeOf(obj, Array.prototype);
Run Code Online (Sandbox Code Playgroud)
(我知道魔术length属性和稀疏数组也有一些问题,但这不是这个问题的重点.)
我想Array.isArray(obj)返回true(当然没有修改Array.isArray()方法).该MDN填充工具为Array.isArray()如下:
Run Code Online (Sandbox Code Playgroud)if (!Array.isArray) { Array.isArray = function(arg) { return Object.prototype.toString.call(arg) === '[object Array]'; }; }
通过使用该Symbol.toStringTag属性,我可以Object.prototype.toString.call(obj)返回'[object Array]':
obj[Symbol.toStringTag] = 'Array';
console.log(Object.prototype.toString.call(obj) === '[object Array]'); // true
Run Code Online (Sandbox Code Playgroud)
现在polyfilled Array.isArray()收益true为obj(请忽略了一个事实,没有一个浏览器不支持Array.isArray()不支持Symbol.toStringTag).然而,本地Array.isArray()函数仍返回false了obj.我查看了ECMAScript 2017规范,它说Array.isArray()使用了抽象操作IsArray,true如果参数是一个Array异常对象,则返回该操作.如果参数是一个代理,它IsArray直接调用目标对象,所以似乎使用代理在这里没有帮助.
有没有办法让 …
我终于将我的组件更新React.createClass()为ES6类.我在测试中看到的第一个错误是我的一些sinon.stub()调用失败,因为jscodeshift -t react-codemod/transforms/class.js转换了我的组件方法以使用属性初始化程序提议,即
class Foo extends React.Component {
componentWillMount() {
this.fetchSomeData(this.props);
}
componentWillReceiveProps(nextProps) {
if (nextProps.someProp !== this.props.someProp) {
this.fetchSomeData(nextProps);
}
}
fetchSomeData = (props) => {
...
};
render() {
...
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:如何fetchSomeData()使用这种新语法存根?我的测试看起来sinon.stub(Foo.prototype, 'fetchSomeData');不再适用,假设因为不再fetchSomeData是原型.
谢谢!
ecmascript-next ×10
javascript ×8
async-await ×4
babeljs ×3
ecmascript-6 ×3
decorator ×2
generator ×2
arrays ×1
class ×1
reactive ×1
reactjs ×1
rxjs ×1
sinon ×1
webpack ×1