怎么让js异步执行函数先执行完了再执行js方法

怎么让js函数 一个执行完之后在执行另外一个?_百度知道
怎么让js函数 一个执行完之后在执行另外一个?
functionstart_flow(){start_project();start_config();...}functionstart_project(){...}functionstart_config(){...}函数中有ajax异步请求所以没有办法使得前一个函数执行完后后一个...
function start_flow(){
start_project();
start_config();
...} function start_project(){
...} function start_config(){
...} 函数中有ajax异步请求
所以 没有办法使得前一个函数执行完后 后一个在执行 现在的问题是start_project()还没有执行完成就开始执行start_config()了,这样会出错,想达到的效果是start_project()执行完成再start_config(),请问要如何做?
有两个可行的方法
settimeout
创立时间差(肯定可行)
确定一个返回值
true 判断返回值
是否执行成功(这个没有试验过
感觉可能不太可行)
我想请问的是
有没有效率高一点的
更好的方法?
答题抽奖
首次认真答题后
即可获得3次抽奖机会,100%中奖。
我爱阿娴゜
来自百度知道认证团队
我爱阿娴゜
采纳数:260
获赞数:1302
擅长:暂未定制
第一种情况:运动函数执行完之后再执行另外一个函数&注释:按钮点击之后,div先显示出来,然后宽度和高度再增加到300px&button class=&btn&&点击我&/button&&div id=&div2&&&p&人的灵魂所必须的东西,是不需要用金钱来买的&/p&&/div&&style&div{height: 200width: 200padding:15background: #display:}&/style&&script&$().ready(function(){$('.btn').click(function(){$('div').show();$('div').animate({ & & & & & &'width':'300px', & & & & & &'height':'300px'},1000)})})71819或者这样写,如果div的高度宽度增加到300px,然后会执行另外一个函数,div的背景色会变成绿色$().ready(function(){$('.btn').click(function(){$('div').show();$('div').animate({ & & & & & &'width':'300px', & & & & & &'height':'300px'},function(){$(this).css('background','green')})})})112第二种情况:把函数a绑定到函数c 上,按钮点击的时候执行函数c,传入的参数是a ,那么函数就先执行函数a(),然后再执行函数b();就形成了先后执行函数$().ready(function(){$('.btn').click(function(){c(a);})})function a() {$('div').animate({'width':'300px'},1000)}function b(){$('div').animate({'height':'300px'},1000)}function c(x){x();b();}
采纳数:189
获赞数:667
1、直接在 start_project 函数中执行start_config&function&start_flow(){&&&&start_project();&&&&//start_config();&&&&...}&function&start_project(){&&&&...&&&&start_config();//&在这里执行}&function&start_config(){&&&&&...}2、或者做成callback函数function&start_flow(){&&&&start_project(&start_config&);&&&&//start_config();&&&&...}&function&start_project(&callback&){&&&&...&&&&if(typeof&callback&!=&&undefined&)&&&&&&&&callback();//&执行调用函数}&function&start_config(){&&&&&...}
采纳数:149
获赞数:246
start_project 添加一个参数,
start_project(fn){………………
fn()}function start_flow(){
start_project(start_config);……}
采纳数:577
获赞数:1000
把start_config()放到start_project()方法中调用
谢谢您的回复
这种方法没有用
采纳数:14411
获赞数:59334
擅长:暂未定制
async: false
谢谢您的回复
原来没用过这个
您说了之后才知道
非常的感谢
本回答被提问者采纳
来自电脑网络类芝麻团
采纳数:407
获赞数:748
参与团队:
在第一个方法执行的最后的地方调用你要执行的第二个函数
谢谢您的回复
这种方法没有用
2条折叠回答
其他3条回答
为你推荐:
其他类似问题
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。请问为什么会在for循环结束才会执行异步函数? - CNode技术社区
这家伙很懒,什么个性签名都没有留下。
请看这段代码:
for(var i=0; i&10; i++){
var now = new Date();
while (new Date - now & 1000);
console.log(&here&);
setTimeout(function(){
console.log(i);
setTimeout在这应该是异步函数吧!我使用了while来使每个循环延迟1s,按理当执行第一次循环执行了setTimeout,他会在后台静默执行,不会阻塞。但是console.log(i);都是在循环执行完成后才会输出。请问这是什么原因?谢谢!
另外我注意到循环结束后立刻输出了4个console.log(i);那应该是执行循环后setTimeout就已经在后台执行了?
输出如下:here
在for里面用自调函数就好了
可否讲详细些,或者给个例子。多谢!:)
可能我的表达有点错误。我不在乎console.log(i);输出的是什么值。而是奇怪为什么要循环结束后才会将console.log(i);输出?
我知道console.log(i); 输出的值是10,但是奇怪的是为什么要循环结束才会输出?而不是在执行循环的时候输出值?
settimeout是js中很重要一个原生函数,也是实现promise的核心。
javascript代码都是同步执行的,代码都在在一个代码“队列”里面。与此同时javascript还有一个“Event Queue”,事件队列里都是处理一些异步的callback/handler,处理ajax response,点击啊,文件,数据库操作结果。关键是,只有代码队列所有代码都执行完毕了,javascript才会从事件队列里取出一个callback/handler来执行。
在你的例子里面,settimeout就是把callback,放到了这个事件队列里面,直到当前的for loop执行完毕了,js才从事件对列里取出callback,才执行了callback函数,找到执行完毕那个状态下的closure 中i的值,并打印出来,所以即使你设置 settimeout(function(){}, 0); 也是同样的结果。
请问为什么会在for循环结束才会执行异步函数?
如果在for循环中执行异步函数,那就不叫异步了。
那是要等for循环结束才会执行异步函数?
那在for循环中执行其他的异步操作也会等循环结束才会执行异步操作吗?另外注意到,循环结束后立刻输出了4个console.log(i);那应该是执行循环后setTimeout就已经在后台执行了?
是的。当前的函数执行完,才轮到后续排队中的程序。setTimeout 里的回调函数在排队中。
setTimeout
不是异步的,实际上它只是伪异步,造成异步的现状是它用了 插入时间点的机制来实现的,setTimeout的第二个参数指明了执行的时间。所以你写的代码执行结果是没问题的 ,
如果楼主不信的话 可以把while写成一个死循环 这样的话 你的setTimeout一辈子都不会执行
for ( var i = 0; i & 5; i++ ) {
setTimeout(function() {
alert( i );
}, i * 100 );
这是JQuery官网上在讲解闭包的时候的一个例子,这里的alert也只会输出5.
参考知乎上的一个
楼上说到点上了。我再补充一点,JS是事件驱动的,你调用的setTimeout函数同步地往事件队列里面加任务而已,因为你添加地任务在事件队列里面,所以肯定是当当前任务执行完了才有机会轮到他们pop出来执行。
所以楼上说 while(1){} 这种死循环会block JS引擎,当前任务不结束,其任务完全没机会执行。
所以Node.js的人建议在执行繁重的计算任务的时候分拆代码并使用 process.nextTick
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。
服务器赞助商为
,存储赞助商为
,由提供应用性能服务。
新手搭建 Node.js 服务器,推荐使用无需备案的代码:&!doctype html&
&html lang="en"&
&meta charset="UTF-8"&
&title&test&/title&
&link rel="stylesheet" href="./style.css"&
&div class="box" id="aa"&123aaaaaasdasdsadsadsadsadsadassssssssssssssssdasdasdasdasdasdddddddddddddd
&div id="ee"&444&div id="tt"&555&/div&&/div&&/div&
&script src="js/common.js"&&/script&
window.onload = function(){
var box = document.getElementById('aa');
addEvent(box,'click',function(){
alert('ysx');
addEvent(box,'click',toBlue);
function toBlue(){
this.className = 'pox';
addEvent(this,'click',toRed);
function toRed(){
this.className = 'box';
addEvent(this,'click',toBlue);
function addEvent(obj,type,fn){
var saved =
if(typeof obj['on'+type] == 'function')saved = obj['on'+type];
obj['on'+type] = function(){
if(saved)saved();
fn.call(this);
}//流程整理:
前期肯定是有预编译期和执行期,这些先不讨论了就,主要说的是这段代码的执行流程
1.是页面加载完成后获取box对象,然后执行函数调用addEvent函数
2.进入addEvent函数,顺序执行,直到遇到一个点击事件后,此时异步执行开始,function(){if(saved)saved();fn.call(this);}这段函数是异步去执行,并且把执行后的结果存在消息队列中,等待主进程来获取消息
3.主进程继续执行下一个addEvent函数调用,然后重复步骤2,因为是同一元素的同一事件,所以在消息队列中只会存在一个事件消息,可以想象成指针(每次让onclick指向堆内存中不同的函数,最后肯定只会执行第一个,但是如果你把对内存中的每个函数都记住自己的上一个,也就是saved指针的功能,相当于一个链表,这样就可以从最早的那个执行了,不会被覆盖)
4.主进程全部执行完成后,等待点击事件发生后,开始在消息队列中获取消息
PS:以上都是自己总结的,肯定漏洞百出,有兴趣的可以讨论一下啊
js函数等待ajax请求执行完再执行之下的js代码
有个js方法 需要return 一个值,这个值需要用ajax获取, ajax是异步的,可能还没有执行完 就已经return 了, 得到的就为空值
将异步请求设为同...
js 满足一个条件后再执行函数,否则一直等待条件成立
回调函数(callback)
function b(b){
function test(){
delay(b,&#input1&,&直的吗...
事件驱动与异步IO
通常,我们写服务器处理模型的程序时,有以下几种模型:(1)每收到一个请求,创建一个新的进程,来处理该请求;
(2)每收到一个请求,创建一个新的线程,来处理该请求;
(3)每收到一个请求,放入一个事件列...
JavaScript:彻底理解同步、异步和事件循环(Event Loop)
一. 单线程
我们常说“JavaScript是单线程的”。
所谓单线程,是指在JS引擎中负责解释和执行JavaScript代码的线程只有一个。不妨叫它主线程。
但是实际上还存在其...
异步事件模型
转载至:http://blog.chinaunix.net/uid--id-94816.html
traffic server设计了一个基于事件驱动的多线程模型,通过...
$(document).ready(function(){
$('#px_ul').on('click','input[type=&button&]',function(){
请尊重原创作品。转载请保持文章完整性,并以超链接形式注明原始作者“tingsking18”和主站点地址,方便其他朋友提问和指正。
以前是用的事件机制来调用JavaScript,事件和回调...
原因:ajax动态加载之前js就加载完了,事件没有绑定到动态生成的dom元素上。
问题:使用on事件,$('#btn').click(function(){})绑定无效
解决方案:使用on绑定事件。$...
代码简单直接贴代码
* 异步加载依赖的javascript文件
* src:script的路径
* callback:当外部的javascript文件被loa...
function connectServer(callback) {
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpReq...
没有更多推荐了,Javascript异步编程的4种方法 - 阮一峰的网络日志
Javascript异步编程的4种方法
你可能知道,Javascript语言的执行环境是"单线程"(single thread)。
所谓"单线程",就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推。
这种模式的好处是实现起来比较简单,执行环境相对单纯;坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法执行。
为了解决这个问题,Javascript语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous)。
"同步模式"就是上一段的模式,后一个任务等待前一个任务结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的;"异步模式"则完全不同,每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。
"异步模式"非常重要。在浏览器端,耗时很长的操作都应该异步执行,避免浏览器失去响应,最好的例子就是Ajax操作。在服务器端,"异步模式"甚至是唯一的模式,因为执行环境是单线程的,如果允许同步执行所有http请求,服务器性能会急剧下降,很快就会失去响应。
本文总结了"异步模式"编程的4种方法,理解它们可以让你写出结构更合理、性能更出色、维护更方便的Javascript程序。
一、回调函数
这是异步编程最基本的方法。
假定有两个函数f1和f2,后者等待前者的执行结果。
如果f1是一个很耗时的任务,可以考虑改写f1,把f2写成f1的回调函数。
  function f1(callback){
    setTimeout(function () {
      // f1的任务代码
      callback();
    }, 1000);
执行代码就变成下面这样:
  f1(f2);
采用这种方式,我们把同步操作变成了异步操作,f1不会堵塞程序运行,相当于先执行程序的主要逻辑,将耗时的操作推迟执行。
回调函数的优点是简单、容易理解和部署,缺点是不利于代码的阅读和维护,各个部分之间高度(Coupling),流程会很混乱,而且每个任务只能指定一个回调函数。
二、事件监听
另一种思路是采用事件驱动模式。任务的执行不取决于代码的顺序,而取决于某个事件是否发生。
还是以f1和f2为例。首先,为f1绑定一个事件(这里采用的jQuery的)。
  f1.on('done', f2);
上面这行代码的意思是,当f1发生done事件,就执行f2。然后,对f1进行改写:
  function f1(){
    setTimeout(function () {
      // f1的任务代码
      f1.trigger('done');
    }, 1000);
f1.trigger('done')表示,执行完成后,立即触发done事件,从而开始执行f2。
这种方法的优点是比较容易理解,可以绑定多个事件,每个事件可以指定多个回调函数,而且可以(Decoupling),有利于实现。缺点是整个程序都要变成事件驱动型,运行流程会变得很不清晰。
三、发布/订阅
上一节的"事件",完全可以理解成"信号"。
我们假定,存在一个"信号中心",某个任务执行完成,就向信号中心"发布"(publish)一个信号,其他任务可以向信号中心"订阅"(subscribe)这个信号,从而知道什么时候自己可以开始执行。这就叫做(publish-subscribe pattern),又称(observer pattern)。
这个模式有多种,下面采用的是Ben Alman的,这是jQuery的一个插件。
首先,f2向"信号中心"jQuery订阅"done"信号。
  jQuery.subscribe("done", f2);
然后,f1进行如下改写:
  function f1(){
    setTimeout(function () {
      // f1的任务代码
      jQuery.publish("done");
    }, 1000);
jQuery.publish("done")的意思是,f1执行完成后,向"信号中心"jQuery发布"done"信号,从而引发f2的执行。
此外,f2完成执行后,也可以取消订阅(unsubscribe)。
  jQuery.unsubscribe("done", f2);
这种方法的性质与"事件监听"类似,但是明显优于后者。因为我们可以通过查看"消息中心",了解存在多少信号、每个信号有多少订阅者,从而监控程序的运行。
四、Promises对象
Promises对象是CommonJS工作组提出的一种规范,目的是为异步编程提供。
简单说,它的思想是,每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数。比如,f1的回调函数f2,可以写成:
  f1().then(f2);
f1要进行如下改写(这里使用的是jQuery的):
  function f1(){
    var dfd = $.Deferred();
    setTimeout(function () {
      // f1的任务代码
      dfd.resolve();
    }, 500);
    return dfd.
这样写的优点在于,回调函数变成了链式写法,程序的流程可以看得很清楚,而且有一整套的,可以实现许多强大的功能。
比如,指定多个回调函数:
  f1().then(f2).then(f3);
再比如,指定发生错误时的回调函数:
  f1().then(f2).fail(f3);
而且,它还有一个前面三种方法都没有的好处:如果一个任务已经完成,再添加回调函数,该回调函数会立即执行。所以,你不用担心是否错过了某个事件或信号。这种方法的缺点就是编写和理解,都相对比较难。
五、参考链接
一、问题的由来
学懂 JavaScript 语言,一个标志就是理解下面两种写法,可能有不一样的结果。
JavaScript 程序越来越复杂,调试工具的重要性日益凸显。客户端脚本有浏览器,Node 脚本怎么调试呢?JavaScript队列函数和异步执行详解
原创
 14:39:29
208
这篇文章主要为大家详细介绍了队列函数和异步执行的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下编辑注:在Review别人的JavaScript代码时曾看到过类似的队列函数,不太理解,原来这个是为了保证函数按顺序调用。读了这篇文章之后,发现还可以用在异步执行等。假设你有几个函数fn1、fn2和fn3需要按顺序调用,最简单的方式当然是:fn1();
fn3();但有时候这些函数是运行时一个个添加进来的,调用的时候并不知道都有些什么函数;这个时候可以预先定义一个数组,添加函数的时候把函数push 进去,需要的时候从数组中按顺序一个个取出来,依次调用:var stack = [];
// 执行其他操作,定义fn1
stack.push(fn1);
// 执行其他操作,定义fn2、fn3
stack.push(fn2, fn3);
// 调用的时候
stack.forEach(function(fn) { fn() }); 这样函数有没名字也不重要,直接把传进去也可以。来测试一下:var stack = [];
function fn1() {
console.log('第一个调用');
stack.push(fn1);
function fn2() {
console.log('第二个调用');
stack.push(fn2, function() { console.log('第三个调用') });
stack.forEach(function(fn) { fn() }); // 按顺序输出'第一个调用'、'第二个调用'、'第三个调用'这个实现目前为止工作正常,但我们忽略了一个情况,就是异步函数的调用。异步是JavaScript 中无法避免的一个话题,这里不打算探讨JavaScript 中有关异步的各种术语和概念,请读者自行查阅(例如某篇著名的评注)。如果你知道下面代码会输出1、3、2,那请继续往下看:console.log(1);
setTimeout(function() {
console.log(2);
console.log(3);假如stack 队列中有某个函数是类似的异步函数,我们的实现就乱套了:var stack = [];
function fn1() { console.log('第一个调用') };
stack.push(fn1);
function fn2() {
setTimeout(function fn2Timeout() {
console.log('第二个调用');
stack.push(fn2, function() { console.log('第三个调用') });
stack.forEach(function(fn) { fn() }); // 输出'第一个调用'、'第三个调用'、'第二个调用' 问题很明显,fn2确实按顺序调用了,但setTimeout里的function fn2Timeout() { console.log(‘第二个调用') }却不是立即执行的(即使把timeout 设为0);fn2调用之后马上返回,接着执行fn3,fn3执行完了然才真正轮到fn2Timeout。 怎么解决?我们分析下,这里的关键在于fn2Timeout,我们必须等到它真正执行完才调用fn3,理想情况下大概像这样:function fn2() {
setTimeout(function() {
fn2Timeout();
}但这样做相当于把原来的fn2Timeout整个拿掉换成一个新函数,再把原来的fn2Timeout和fn3插进去。这种动态改掉原函数的写法有个专门的名词叫Monkey Patch。按我们程序员的口头禅:“做肯定是能做”,但写起来有点拧巴,而且容易把自己绕进去。有没更好的做法? 我们退一步,不强求等fn2Timeout完全执行完才去执行fn3,而是在fn2Timeout函数体的最后一行去调用:function fn2() {
setTimeout(function fn2Timeout() {
console.log('第二个调用');
}这样看起来好了点,不过定义fn2的时候都还没有fn3,这fn3哪来的?还有一个问题,fn2里既然要调用fn3,那我们就不能通过stack.forEach去调用fn3了,否则fn3会重复调用两次。我们不能把fn3写死在fn2里。相反,我们只需要在fn2Timeout末尾里找出stack中fn2的下一个函数,再调用:function fn2() {
setTimeout(function fn2Timeout() {
console.log('第二个调用');
}这个next函数负责找出stack 中的下一个函数并执行。我们现在来实现next:var index = 0;
function next() {
var fn = stack[index];
index = index + 1; // 其实也可以用shift 把fn 拿出来
if (typeof fn === 'function') fn();
}next通过stack[index]去获取stack中的函数,每调用next一次index会加1,从而达到取出下一个函数的目的。next这样使用:var stack = [];
// 定义index 和next
function fn1() {
console.log('第一个调用');
next(); // stack 中每一个函数都必须调用`next`
stack.push(fn1);
function fn2() {
setTimeout(function fn2Timeout() {
console.log('第二个调用');
next(); // 调用`next`
stack.push(fn2, function() {
console.log('第三个调用');
next(); // 最后一个可以不调用,调用也没用。
next(); // 调用next,最终按顺序输出'第一个调用'、'第二个调用'、'第三个调用'。现在stack.forEach一行已经删掉了,我们自行调用一次next,next会找出stack中的第一个函数fn1执行,fn1 里调用next,去找出下一个函数fn2并执行,fn2里再调用next,依此类推。每一个函数里都必须调用next,如果某个函数里不写,执行完该函数后程序就会直接结束,没有任何机制继续。了解了函数队列的这个实现后,你应该可以解决下面这道面试题了:// 实现一个LazyMan,可以按照以下方式调用:
LazyMan(“Hank”)
Hi! This is Hank!
LazyMan(“Hank”).sleep(10).eat(“dinner”)输出
Hi! This is Hank!
// 等待10秒..
Wake up after 10
Eat dinner~
LazyMan(“Hank”).eat(“dinner”).eat(“supper”)
Hi This is Hank!
Eat dinner~
Eat supper~
LazyMan(“Hank”).sleepFirst(5).eat(“supper”)
/* 等待5秒,输出
Wake up after 5
Hi This is Hank!
Eat supper
// 以此类推。 中大名鼎鼎的connect正是这样实现队列的。有兴趣可以去看看它的源码或者这篇解读《何为 connect 中间件》。细心的你可能看出来,这个next暂时只能放在函数的末尾,如果放在中间,原来的问题还会出现:function fn() {
console.log(1);
console.log(2); // next()如果调用了异步函数,console.log(2)就会先执行
}redux 和koa 通过不同的实现,可以让next放在函数中间,执行完后面的函数再折回来执行next下面的代码,非常巧妙。有空再写写。以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。以上就是JavaScript队列函数和异步执行详解的详细内容,更多请关注php中文网其它相关文章!
江湖传言:PHP是世界上最好的编程语言。真的是这样吗?这个梗究竟是从哪来的?学会本课程,你就会明白了。
PHP中文网出品的PHP入门系统教学视频,完全从初学者的角度出发,绝不玩虚的,一切以实用、有用...
点击数(111857)
ThinkPHP是国内最流行的中文PHP开发框架,也是您Web项目的最佳选择。《php.cn独孤九贱(5)-ThinkPHP5视频教程》课程以ThinkPHP5最新版本为例,从最基本的框架常识开始,将...
点击数(109871)
《php.cn原创html5视频教程》课程特色:php中文网原创幽默段子系列课程,以恶搞,段子为主题风格的php视频教程!轻松的教学风格,简短的教学模式,让同学们在不知不觉中,学会了HTML知识。
点击数(84329)
本套教程,以一个真实的学校教学管理系统为案例,手把手教会您如何在一张白纸上,从零开始,一步一步的用ThinkPHP5框架快速开发出一个商业项目。
点击数(83472)
所有计算机语言的学习都要从基础开始,《PHP入门视频教程之一周学会PHP》不仅是PHP的基础部分更主要的是PHP语言的核心技术,是学习PHP必须掌握的内容,任何PHP项目的实现都离不开这部分的内容,通...
点击数(80800)
全栈工程师
文章总浏览数
相关视频章节

我要回帖

更多关于 promisejs异步执行完毕 的文章

 

随机推荐