У меня есть функция (f1), которую я хочу вызывать только после выполнения двух вызовов ajax (скажем, a1 и a2). a2 следует вызывать только после того, как выполнено a1. Ниже приведена последовательность операций =
$.when(a1 and a2) {
f1
}
Я попробовал следующий фрагмент кода -
$.when(a1a2()).done(function(){
f1();
}
var a1a2 = function(){
return $.when(a1()).done(function() {
if (<check for a few variables a1 sets>) {
// another ajax call for which f1 should wait
return a2();
} else {
// random function for which f1 shouldn't wait
f2();
}
});
}
В приведенном выше коде f1 ожидает завершения a1, но не ждет завершения a2.
Я также попробовал следующий фрагмент кода (но он также просто ждет завершения a1) -
var a1a2 = function(){
var retVal = new Promise(function(){
a1().then(function(){
if (<check for a few variables a1 sets>) {
return a2();
} else {
// random function for which f1 shouldn't wait
f2();
}
});
});
}
Я просмотрел другие подобные вопросы, но не смог найти решение. Может кто-нибудь помочь?
Возможный дубликат Разрешить обещания одно за другим (т.е. последовательно)?
Позвоните a1
, чтобы получить свое Обещание, затем позвоните Promise.all
на a1
и a1
, связанном с a2
:
const a1Prom = a1();
Promise.all([
a1Prom,
a1Prom.then(a2)
])
.then(f1);
console.info('script start');
const delay = ms => new Promise(res => setTimeout(res, ms));
const a1 = () => delay(1000).then(() => console.info('a1 done'));
const a2 = () => {
console.info('a2 starting');
return delay(1000).then(() => console.info('a2 done'));
};
const f1 = () => console.info('f1 starting');
const a1Prom = a1();
Promise.all([
a1Prom,
a1Prom.then(a2)
])
.then(f1);
Это не сработало для меня, оно не ждет выполнения a2. a2 не возвращает никаких обещаний
Да, вам нужно убедиться, что a2
возвращает промис, чтобы использовать его с асинхронным кодом, подобным этому (но вы не опубликовали код a2
). Если вы это сделаете, нажмите «Выполнить фрагмент кода», вы увидите, что он работает как нужно.
Есть ли способ вернуть обещание или ноль (если я не хочу ждать)
Я не знаком с синтаксисом when/done, но это исправление для вашего второго фрагмента. Большой намек, который я хотел бы дать, заключается в том, что использование new Promise
— плохая идея в 90% случаев.
var a1a2 = function(){
var retVal = a1().then(function(){
if (<check for a few variables a1 sets>) {
return a2();
} else {
// random function for which f1 shouldn't wait
f2();
}
});
});
Во-первых, ваш промис-код неверен, потому что вы неправильно создаете промис.
new Promise(function(resolve, reject) {
// in here you call resolve or reject otherwise Promise is forever pending
});
Однако, поскольку a1
возвращает обещание (как и все функции, я предполагаю), вам не нужно создавать обещание.
Итак, ваш код будет
a1()
.then(function() {
if (somecondition == true) {
return a2();
} else {
f2(); // since there's no return here, there's no "wait" for the promise f2 returns
}
})
.then(function() {
return f1();
})
Чтобы проиллюстрировать вышесказанное, вот ваш код один раз с условием true, а затем с условием false
Обратите внимание на «метки времени» для вывода консоли.
// dummy code to set up some promises
const dummy = (x, d=1000) => {
console.info(performance.now(), 'start', x);
return new Promise(resolve => setTimeout(() => {
console.info(performance.now(), 'end', x);
resolve(x);
}, d));
};
const a1 = () => dummy('a1');
const a2 = () => dummy('a2');
const f1 = () => dummy('f1');
const f2 = () => dummy('f2', 3000);
// end dummy code
console.info('wait for a2');
a1()
.then(function() {
if (true) {
return a2();
} else {
// random function for which f1 shouldn't wait
f2();
}
})
.then(function() {
return f1();
})
.then(() => {
console.info('dont wait for f2');
a1()
.then(function() {
if (false) {
return a2();
} else {
// random function for which f1 shouldn't wait
f2();
}
})
.then(function() {
f1();
});
});
However! If f2 is a function that has no asynchrony then there is no way * to prevent f1 from being called after f2 finish - because that's how javascript works
* - I guess you could put it in a setTimeout, then f2 would execute after f1 begins (again, assuming f1 has some asynchrony, otherwise f2 would begin after f1 ends)
function a1() {
return new Promise(resolve => {
resolve();
});
}
function a2() {
return new Promise(resolve => {
resolve();
});
}
function f1() {
// this runs when the a1 and a2 is resolved.
}
// this is the call method. there are so many approach in your question first is chaining of promise.
function CallMethod(){
a1().then(function () { // you can optionally pass data here via the resolve in the promise
return a2();
}).then(function () { // same here you can pass optional data here.
// here the a1 and a2 is resolved you can call the f1() now.
f1();
});
}
// second one is called Promise.all()
function CallMethod() {
Promise.all([a1(), a2()]).then(data => { // this is the optional data passed in the resolve base on the index of the function promises.
var firstResolve = data[0]; // resolved data of a1();
var secondResolve = data[1]; // resolved data of a2();
})
}
new Promise(function(){
это НЕ то, как вы создаете обещание - это обещание останется в ожидании навсегда