Вопрос:
* Примечание: повторный вопрос:
Я пытаюсь написать следующие внешние для вызовов отдельных функций:
Пример:
function f1(){ do something 1 } function f2(){ do something 2 } run function 1 when done run function 2
(см. комментарии ниже для jsfiddles)
Проблема в том, что ящики загружаются одновременно. Поведение СЛЕДУЕТ быть, нагружать красным, когда это делается, загружать зеленый цвет.
Если это не обычный метод в jQuery, дайте мне знать, может быть, я просто преследую призрак…
Лучший ответ:
Вы можете просто вызвать вторую функцию в конце первой.
$(document).ready(function() { function firstFunction(){ alert(«this is the first function!»); secondFunction(); } function secondFunction(){ alert(«this is the second function!»); } firstFunction(); });
В качестве альтернативы, если вы не хотите вызывать вторую функцию каждый раз, когда вы вызываете первый, вы можете просто вызвать их последовательно
firstFunction(); secondFunction();
Это работает, потому что он будет ждать, пока firstFunction не будет выполнен, прежде чем он перейдет к secondFunction
fiddle
Ответ №1
Зависит от функций.
Краткий ответ:
Для синхронных функций: просто назовите их один за другим.
Для асинхронных функций: зависит от того, что делает его асинхронным.
jQuery анимации? Определите параметр обратного вызова из метода анимации или из объекта Promise очереди fx.
setTimeout/setInterval/что-то еще? Скорее всего, функции нужно будет переписать, чтобы обеспечить объект обратного вызова или отложенного/обещания.
Смотрите примеры или .
Длинный ответ:
Согласно jsFiddles в ваших комментариях, у вас есть две функции:
function firstFunction(){ $(«.one»).fadeIn(1000).delay(2000).fadeOut(); } function secondFunction(){ $(«.two»).fadeIn(1000).delay(2000).fadeOut(); }
Вы хотите, чтобы secondFunction запускался после firstFunction, и вы предпочтете не вмешиваться в эти функции. Если в этом случае есть только одно решение, о котором я могу думать: Получите объект Promise из элемента, который анимация firstFunction, а затем определите secondFunction как обработчик успеха:
firstFunction(); $(‘.one’).promise().then(secondFunction);
promise() возвращает объект Promise, связанный с текущим состоянием анимации этого элемента. $(‘.one’).promise().then(secondFunction) по существу говорит: “Я обещаю запустить secondFunction, когда текущая анимация для .one выполнена.
Если вы хотите вмешаться в существующие функции, вы также можете вызвать secondFunction как параметр обратного вызова fadeOut внутри firstFunction, но это не очень изящное решение.
Если вы хотите переписать свои функции, идеальным решением является приручение ваших асинхронных функций с помощью “Отложенные” и Promises. Здесь быстрый праймер:
- В jQuery объект Deferred – это специальный объект, который вы можете использовать для определения состояния успеха/отказа функции. Вы используете это в своих функциях.
- Объект Promise – это особый объект, который можно использовать для добавления обратных вызовов для этих состояний успеха/отказа. Вы используете это вне своих функций.
Используя эти инструменты, вы можете переписать свои функции, чтобы указать, когда они “сделаны”, и вы можете предоставить код вне своих функций возможность узнать, когда (и выполнить после) они будут выполнены.
Переписанный для использования отложенных и обещаний, код выглядит следующим образом:
function firstFunction(){ var deferred = $.Deferred(); $(«.one»).fadeIn(1000).delay(2000).fadeOut(function() { deferred.resolve(); }); return deferred.promise(); } function secondFunction(){ var deferred = $.Deferred(); $(«.two»).fadeIn(1000).delay(2000).fadeOut(function() { deferred.resolve(); }); return deferred.promise(); } firstFunction().then(secondFunction);
Если все ваши функции написаны таким образом, вы можете контролировать их порядок выполнения и запускать их последовательно, используя then(). Вот более обстоятельный пример:
function one(){ var deferred = $.Deferred(); $(«.one»).fadeOut(500, function() { $(this).appendTo(‘body’).fadeIn(500, function() { deferred.resolve(); }); }); return deferred.promise(); } function two(){ var deferred = $.Deferred(); $(«.two»).fadeOut(1500, function() { $(this).appendTo(‘body’).fadeIn(500, function() { deferred.resolve(); }); }); return deferred.promise(); } function three(){ var deferred = $.Deferred(); $(«.three»).fadeOut(1000, function() { $(this).appendTo(‘body’).fadeIn(500, function() { deferred.resolve(); }); }); return deferred.promise(); } function four(){ var deferred = $.Deferred(); $(«.four»).fadeOut(750, function() { $(this).appendTo(‘body’).fadeIn(500, function() { deferred.resolve(); }); }); return deferred.promise(); } function five(){ var deferred = $.Deferred(); $(«.five»).fadeOut(600, function() { $(this).appendTo(‘body’).fadeIn(500, function() { deferred.resolve(); }); }); return deferred.promise(); } one() .then(two) .then(three) .then(four) .then(five);
Ответ №2
вы можете использовать функцию jquery Callbacks, начиная с v1.7up
var callbacks = $.Callbacks(); callbacks.add( firstFunction ); callbacks.add( secondFunction ); callbacks.fire( ); Ответ №3
Отсрочка – это вариант. Вы всегда можете сделать следующее:
$.when(firstFunction()).then(secondFunction);
Единственный трюк в том, что внутри firstFunction вам нужно будет сделать следующее:
function firstFunction(){ var deferred = $.Deffered(); $.get(url,function(r){ deferred.resolve(); }); return deferred; }
Когда функция будет ждать, пока не будет отменена отсрочка, возвращаемая вызовом firstFunction. Как только отложенная решена (в обратном вызове ajax), оператор “.then” срабатывает, вызывая вашу вторую функцию.
Документы jQuery очень хорошо объясняют Deferred API.
Ответ №4
вместо
firstFunction(function(){ secondFunction(); });
записи
firstFunction(); secondFunction(); Ответ №5
У меня была эта проблема в последнее время. Если у вас есть куча функций, которые делают асинхронные вещи, просто заставьте их всех вернуть Отложенное, которое вы вручную разрешите, когда задание async функции закончено. Затем вы можете поместить функции в массив и запустить их последовательно:
// Sample asynchronous function that returns Deferred var f = function(name){ console.log(‘Function root start’, name); var d = $.Deferred(); d.done(function(result){ console.log(‘Async work finish’, name, result); }); setTimeout(function(){ setTimeout(function(){ d.resolve(‘Hello’); }, 200); }, 1000); console.log(‘Function root finish’, name); return d; }; // Array with functions var defs = []; defs.push(f.bind(null, 1)); defs.push(f.bind(null, 2)); defs.push(f.bind(null, 3)); // Recursive sequential calling var i = 0; var runAtIndex = function (i) { i < defs.length && defs[i]().done(function() { runAtIndex(i + 1); }); } runAtIndex(i);