JavaScript的诺言 - 等待清晰度的运动上
之前,我有一个要求做到以下几点:JavaScript的诺言 - 等待清晰度的运动上
- 通过调用内部函数获取的“线”的列表(getLines())。
- 选择第一行,执行一个动作
- 以往的动作完成后,选择下一行,做同样的动作
- 重复所有线路(3-20取决于用户)
我有下面的代码代替:
App.Lines = response.data;
for (var _i = 0; _i < App.Lines.length; _i++) {
var makeCallPromise = new Promise(
function(resolve, reject) {
Session.connection.ol.makeCall(App.Lines[_i], callBackFunction(response) {
//this can take up to 30 seconds to respond...
resolve(response.data);
}, errorCallBackFunction(message) {
reject(message.error);
}, bareJid);
}
)
makeCallPromise.then(function(fulfilled) {
console.log("PROMISE WORKED!!!!!", fulfilled);
})
.catch(function(error) {
console.log("PROMISE FAILED!!!!!", error);
});
}
我的希望是,循环将等待解决的承诺,它继续循环之前,然而,事实并非如此。 我的问题是在分辨率完成之前是否可以暂停循环。 注 - 我正在使用蓝鸟JS库作为承诺。 谢谢!
亲切的问候,
加里
可以使用Promise.each()通过蓝鸟提供,这将依次遍历数组,并等待他们移动到下一个元素的数组
我已经尝试通过迭代承诺并创建它们的数组(而不是在迭代中解决它们)。然后我调用Promise.each(promiseArray,function(result){console.log(result)}。然后(function(fulfilled){console.log(“WORKED”)})。catch(function(error){的console.log( “ERROR”)}));”。问题是这不起作用,它仍然尝试执行Session.connection.ol.makeCall而不等待第一个解决。 – Gary
你使用蓝鸟吗? – marvel308
嗯我已经通过将它包含在
我在之前解决不知道蓝鸟,但你可以做类似的事情来创建某种for循环,等待每个承诺在下一次迭代之前结束。
这是一个普通的例子,它当然可以进行优化,它只是一个快速的尝试:
var i = 0;
var performAsyncOperation = function(operationNumber) {
return new Promise(function(resolve, reject){
console.log('Operation number', operationNumber);
resolve();
});
}
var chainAsyncOperations = function() {
if(++i < 10) {
return performAsyncOperation(i).then(chainAsyncOperations);
}
};
performAsyncOperation(i).then(chainAsyncOperations);
希望这会帮助你;)
这个用例完全匹配的ES7功能async await
,如果您在使用babeljs到transpile你的代码的可能性,你可以重构你的函数是这样的:
function createPromise(line) {
return new Promise(
function(resolve, reject) {
Session.connection.ol.makeCall(line, callBackFunction(response) {
//this can take up to 30 seconds to respond...
resolve(response.data);
}, errorCallBackFunction(message) {
reject(message.error);
}, bareJid);
}
);
}
App.Lines = response.data;
async function main() {
for (var _i = 0; _i < App.Lines.length; _i++) {
try {
var result = await createPromise(App.Lines[_i]);
console.log(result);
} catch (err) {
console.log(err);
}
}
}
main().then(function() {
console.log('finished');
});
您应该使用Bluebird#each
方法:
。每个(函数(任何项目,INT索引,INT长度)迭代) - >无极
迭代数组或数组,其中包含的承诺一个承诺(或与给定的具有签名(值,索引,长度)的迭代器函数的承诺和值的组合),其中值是输入数组中相应承诺的解析值。迭代发生连续。如果输入数组中的任何承诺被拒绝,返回的承诺也会被拒绝。
Promise.each(App.Lines, line => {
return new Promise((resolve, reject) => {
Session.connection.ol.makeCall(line, callBackFunction(response) {
resolve(response.data);
}, errorCallBackFunction(message) {
reject(message.error);
}, bareJid);
})
.then(fulfilled => console.log("PROMISE WORKED!!!!!", fulfilled))
.catch(err => onsole.log("PROMISE FAILED!!!!!", err));
});
嗨,这不起作用,我真的不明白它在做什么。在1行值的简单情况下,它看起来像在同一时刻发出两次'Session.connection.ol.makeCall',所以我们立即失败。当我将它更新为2行时,它会立即发出4个'Session.connection.ol.makeCall',然后在响应返回后再发出2个。 – Gary
根据你的问题中的代码,'App.Lines'是一行数组,在我的代码中,我使用'Bluebird#each'方法遍历数组,并为每一行调用'Session.connection.ol.makeCal'。你确定'App.Lines'在第一种情况下有一行(一个元素),第二种情况下有两行?在Promise.each之前添加'console.log(App.Lines.length)'。 – alexmac
我认为你必须以某种方式“返回”承诺。就像在这种情况下,“履行”是你在诺言中使用的关键词。 – ZombieChowder
而不是循环整个事情,循环makeCallPromise并将这些承诺推送到一个数组。然后使用Promise.all(array)并在promise.all后添加'then()'调用。结果将会是所有的promsies都会在调用第一个'then()'之前解析,所以所有的数据都可以重新循环。或者,根本不要使用循环,但在前者解析后进行下一次makeCallPromise。 – Shilly
@Shilly谢谢,我已经尝试在由marvel308提供的答案中使用此方法,并使用Promise.each()。我的回应是关于我所做的和发生的事情。 – Gary