A.B*_*oll 3 javascript promise bluebird
我一直在学习使用蓝鸟两周的承诺.我对他们大多了解,但我去解决一些相关的问题,似乎我的知识已经崩溃了.我正在尝试这个简单的代码:
var someGlobal = true;
whilePromsie(function() {
return someGlobal;
}, function(result) { // possibly even use return value of 1st parm?
// keep running this promise code
return new Promise(....).then(....);
});
Run Code Online (Sandbox Code Playgroud)
作为一个具体的例子:
// This is some very contrived functionality, but let's pretend this is
// doing something external: ajax call, db call, filesystem call, etc.
// Simply return a number between 0-999 after a 0-999 millisecond
// fake delay.
function getNextItem() {
return new Promise.delay(Math.random()*1000).then(function() {
Promise.cast(Math.floor(Math.random() * 1000));
});
}
promiseWhile(function() {
// this will never return false in my example so run forever
return getNextItem() !== false;
}, // how to have result == return value of getNextItem()?
function(result) {
result.then(function(x) {
// do some work ...
}).catch(function(err) {
console.warn("A nasty error occured!: ", err);
});
}).then(function(result) {
console.log("The while finally ended!");
});
Run Code Online (Sandbox Code Playgroud)
现在我完成了我的作业!有同样的问题,但在这里面向Q.js:
但是接受的答案以及其他答案:
现在,有是关于使用这个异步()方法RSVP答案.真正令我困惑的是bluebird文档,我甚Promise.async()至在存储库中看到了调用的代码,但我在最新的bluebird副本中看不到它.它只在git存储库中还是什么?
jfr*_*d00 13
这并不是100%清楚你想要做什么,但我会写一个答案来做你提到的以下事情:
首先,假设您有一些异步函数返回一个promise,其结果用于确定是否继续循环.
function getNextItem() {
return new Promise.delay(Math.random()*1000).then(function() {
return(Math.floor(Math.random() * 1000));
});
}
Run Code Online (Sandbox Code Playgroud)
现在,您希望循环,直到返回的值满足某些条件
function processLoop(delay) {
return new Promise(function(resolve, reject) {
var results = [];
function next() {
getNextItem().then(function(val) {
// add to result array
results.push(val);
if (val < 100) {
// found a val < 100, so be done with the loop
resolve(results);
} else {
// run another iteration of the loop after delay
setTimeout(next, delay);
}
}, reject);
}
// start first iteration of the loop
next();
});
}
processLoop(100).then(function(results) {
// process results here
}, function(err) {
// error here
});
Run Code Online (Sandbox Code Playgroud)
如果你想让它更通用,那么你可以传递函数和比较,你可以这样做:
function processLoop(mainFn, compareFn, delay) {
return new Promise(function(resolve, reject) {
var results = [];
function next() {
mainFn().then(function(val) {
// add to result array
results.push(val);
if (compareFn(val))
// found a val < 100, so be done with the loop
resolve(results);
} else {
// run another iteration of the loop after delay
if (delay) {
setTimeout(next, delay);
} else {
next();
}
}
}, reject);
}
// start first iteration of the loop
next();
});
}
processLoop(getNextItem, function(val) {
return val < 100;
}, 100).then(function(results) {
// process results here
}, function(err) {
// error here
});
Run Code Online (Sandbox Code Playgroud)
您尝试这样的结构:
return getNextItem() !== false;
Run Code Online (Sandbox Code Playgroud)
无法工作,因为getNextItem()返回一个承诺,!== false因为承诺是一个对象,所以无法工作.如果你想测试一个promise,你必须使用它.then()来获取它的值,你必须异步执行comparson所以你不能直接返回这样的值.
注意:虽然这些实现使用调用自身的函数,但这不会导致堆栈堆积,因为它们会异步调用自身.这意味着在函数再次调用自身之前,堆栈已经完全展开,因此没有堆栈构建.这将始终是.then()处理程序的情况,因为Promise规范要求.then()在堆栈返回到"平台代码"之前不调用.then()处理程序,这意味着它在调用处理程序之前已解开所有常规"用户代码" .
在ES7中使用async和await
在ES7中,您可以使用async并等待"暂停"循环.这可以使这种类型的迭代更容易编码.这在结构上看起来更像是典型的同步循环.它用于await等待promises,因为声明了函数async,它总是返回一个promise:
function delay(t) {
return new Promise(resolve => {
setTimeout(resolve, t);
});
}
async function processLoop(mainFn, compareFn, timeDelay) {
var results = [];
// loop until condition is met
while (true) {
let val = await mainFn();
results.push(val);
if (compareFn(val)) {
return results;
} else {
if (timeDelay) {
await delay(timeDelay);
}
}
}
}
processLoop(getNextItem, function(val) {
return val < 100;
}, 100).then(function(results) {
// process results here
}, function(err) {
// error here
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3185 次 |
| 最近记录: |