[英]await / observe within function
我无法理解这一点。 如何等待 i==2 完成,然后再继续其他 i?
class Observable {
constructor() {
this.observers = [];
}
subscribe(f) {
this.observers.push(f);
}
unsubscribe(f) {
this.observers = this.observers.filter(subscriber => subscriber !== f);
}
notify(data, options) {
this.observers.forEach(observer => observer(data));
}
}
let myObserver = new Observable();
for (let i=0; i <= 2; i++){
let proc = async function processor(foo) {
console.log('Processing ' + i + ' ' + foo);
if (i != 2){
//await for i = 2 to finish
//??? <----
}
// do other stuff which requires i = 2
await new Promise(r => setTimeout(r, i * 1000));
console.log('Done ' + i);
}
myObserver.subscribe(proc);
}
myObserver.notify('Hello');
我添加了一个更具体的示例 - 可能会阐明我实际尝试完成的工作。 (使用与上面相同的 Observable class)
let allData = {};
let dataProviders = {
provderA: {
url: 'http://provder.a.com',
observer: new Observable(),
requires: null
},
providerB: {
url: 'http://provder.b.com',
observer: new Observable(),
requires: 'providerA'
}
}
let consumers = {
consumerX: {
provider: 'providerA'
},
consumerY: {
provider: 'providerB'
},
consumerZ: {
provider: 'providerB'
}
}
function getData(providerName) {
let urlParam = '';
if (dataProviders[providerName][requires] != null) {
// (a)wait for providerA / dataProviders[providerName][requires]
// ??? <----
urlParam += allData[dataProviders[providerName][requires]]['parameter']
}
$.getJSON(dataProviders[providerName][url] + urlParam).done(function (result) {
allData[providerName] = result;
dataProviders[providerName][observer].notify(allData)
});
}
for (const consumer of Object.keys(consumers)) {
let subscription = function (data) {
console.log('process data');
console.log(data)
}
dataProviders[consumers[consumer]['provider']].subscribe(subscription);
}
for (const providerName of Object.keys(dataProviders)) {
getData(providerName);
}
我怀疑你正在寻找
async function getData(providerName) {
const { url, requires } = dataProviders[providerName];
let urlParam = '';
if (requires != null) {
const requiredData = await new Promise(resolve => {
dataProviders[requires].observer.subscribe(() => {
resolve(allData[requires]);
});
// getData(requires); ???
});
urlParam += requiredData.parameter;
}
const result = await $.getJSON(url + urlParam);
allData[providerName] = result;
dataProviders[providerName][observer].notify(allData);
}
如果您没有向观察者通知具体result
,而不是allData
,则可以简化resolve
r 回调的订阅。 但是,我想您可以完全放弃Observer
class 并使用 promise 代替,如果您不多次获取数据。 这将允许您摆脱allData
存储,只需记住getData
返回的 promise ,从而大大简化整个代码:
const dataProviders = {
provderA: {
url: 'http://provder.a.com',
promise: null,
requires: null
},
providerB: {
url: 'http://provder.b.com',
promise: null,
requires: 'providerA'
}
};
function getDataOnce(providerName) {
const provider = dataProviders[providerName];
if (provider.promise == null)
provider.promise = getData(provider);
return provider.promise;
}
async function getData({ url, requires }) {
let urlParam = '';
if (requires != null) {
const requiredData = await getDataOnce(requires);
urlParam += requiredData.parameter;
}
const result = await $.getJSON(url + urlParam);
return result;
}
const consumers = {
consumerX: {
provider: 'providerA'
},
consumerY: {
provider: 'providerB'
},
consumerZ: {
provider: 'providerB'
}
};
for (const consumer of Object.values(consumers)) {
getDataOnce(consumer.provider).then(data =>
console.log('process data');
console.log(data)
});
}
您可以在此处使用 promise。
async function getData(providerName) {
if (dataFromAnotherProviderIsNeeded) {
// wait till promise resolve
await new Promise( async (resolve) => {
await getData(anotherProvider);
// when request is done, resolve
resolve();
};
}
// Previous request is done
}
另一种选择是使用 rxjs 中的 concat 等到第一个请求发出后再执行第二个请求(使用 rxjs 功能更强大,但在简单的情况下可能不需要)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.