Ant*_*ung 14 javascript asynchronous generator callback es6-promise
你有一个原型对象Foo有两个异步方法调用,bar和baz.
var bob = new Foo()
Foo.prototype.bar = function land(callback) {
setTimeout(function() {
callback()
console.log('bar');
}, 3000);
};
Foo.prototype.baz = function land(callback) {
setTimeout(function() {
callback()
console.log('baz');
}, 3000);
};
Run Code Online (Sandbox Code Playgroud)
我们想做bob.bar().baz()并按顺序记录"bar"和"baz".
如果你不能修改方法调用(包括传入你的回调函数),你如何将默认回调传递给这些方法调用?
一些想法:
用装饰器包裹"bob"(如何实现仍然模糊,可以用一个小例子)
修改构造函数以指定默认回调(如果没有分配)(未考虑是否可能)
使用生成器包装器将继续调用next方法,直到没有剩下?
更推荐的方法是使用promises.因为这是社区范围内做异步事物的趋势.
我们想做bob.bar().baz()并按顺序记录"bar"和"baz".
你为什么要这样做才能实现这种bob.bar().baz()"语法"?当你可以做到这一点时,只需使用Promise API而不需要额外的努力来使语法工作确实增加了代码复杂性,使得实际代码难以理解.
因此,您可能需要考虑使用类似于此的基于承诺的方法,它提供的灵活性远远超过您的方法所实现的灵活性:
Foo.prototype.bar = function () {
return new Promise(function (resolve) {
setTimeout(function () {
resolve()
console.log('bar');
}, 3000);
};
};
Foo.prototype.baz = function () {
return new Promise(function (resolve) {
setTimeout(function () {
resolve()
console.log('baz');
}, 3000);
};
};
Run Code Online (Sandbox Code Playgroud)
现在你这样做是为了一个接一个地顺序运行它们:
var bob = new Foo();
bob.bar().then(function() {
return bob.baz();
});
// If you're using ES2015+ you could even do:
bob.bar().then(() => bob.baz());
Run Code Online (Sandbox Code Playgroud)
如果您需要链接更多功能,您可以简单地执行此操作:
bob.bar()
.then(() => bob.baz())
.then(() => bob.anotherBaz())
.then(() => bob.somethingElse());
Run Code Online (Sandbox Code Playgroud)
无论如何,如果你不习惯使用承诺,你可能想要读这个
警告这还不太正确。理想情况下,我们将Promise子类化,并具有适当的then / catch功能,但是将bluebird Promise子类化也有一些警告。这个想法是存储一个内部的promise生成函数数组,然后当一个Promise被等待(然后/ await)顺序地等待这些promise时。
const Promise = require('bluebird');
class Foo {
constructor() {
this.queue = [];
}
// promise generating function simply returns called pGen
pFunc(i,pGen) {
return pGen();
}
bar() {
const _bar = () => {
return new Promise( (resolve,reject) => {
setTimeout( () => {
console.log('bar',Date.now());
resolve();
},Math.random()*1000);
})
}
this.queue.push(_bar);
return this;
}
baz() {
const _baz = () => {
return new Promise( (resolve,reject) => {
setTimeout( () => {
console.log('baz',Date.now());
resolve();
},Math.random()*1000);
})
}
this.queue.push(_baz);
return this;
}
then(func) {
return Promise.reduce(this.queue, this.pFunc, 0).then(func);
}
}
const foo = new Foo();
foo.bar().baz().then( () => {
console.log('done')
})
Run Code Online (Sandbox Code Playgroud)
结果:
messel@messels-MBP:~/Desktop/Dropbox/code/js/async-chain$ node index.js
bar 1492082650917
baz 1492082651511
done
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13215 次 |
| 最近记录: |