在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/HTML/ 回調(diào)函數(shù)運(yùn)行的順序

回調(diào)函數(shù)運(yùn)行的順序

代碼如下,data是長度為3的一個數(shù)組,cmt是個object

function addComments(campground, cmt) {
    Comment.create(
        cmt,
        function(err, comment) {
            if (err) console.log(err);
            else {
                campground.comments.push(comment);
                campground.save();
                console.log("Created new comment");
        }
    });
}
    
function addCamps(seed) {
    Camp.create(seed, function(err, campground){
        if (err) console.log(err);
        else {
            console.log("Added a campground");
            addComments(campground, cmt);    
        }
    });
}


function seedDB(){
    Camp.remove({}, function(err) {
        if (err) console.log(err);
        else {
            console.log("removed campgrounds");
            Comment.remove({}, function(err) {
                if (err) console.log(err);
                else {
                    console.log("removed comments");                    
                    data.forEach(addCamps);
                }
            });
        }   
    });
}

seedDB();

請問為什么輸出結(jié)果是

removed campgrounds
removed comments
Added a campground
Added a campground
Added a campground
Created new comment
Created new comment
Created new comment

而不是

removed campgrounds
removed comments
Added a campground
Created new comment
Added a campground
Created new comment
Added a campground
Created new comment

如果想讓結(jié)果變成第二種情況,應(yīng)該如何修改以上代碼?
應(yīng)該如何修改以上代碼?

回答
編輯回答
清夢

因為回調(diào)函數(shù)的特點(diǎn)就是無需等待,且回調(diào)執(zhí)行的時間也不確定。你這里出現(xiàn)這種輸出順序的原因是執(zhí)行addComments時花了些時間。

如果你想要按Added a campground、Created new comment這樣交替打印的話,就需要等待前一個 comment完成再執(zhí)行下一個capmgroup的添加了。這就放棄了js異步的優(yōu)勢?,F(xiàn)在data數(shù)據(jù)只有三個不算多,但是數(shù)據(jù)一多就會影響體驗,用戶會看到最后面的comment添加的比第一個遲的多。

代碼的話可以用Promise:

function addComments(campground, cmt,resolve) {
  Comment.create(cmt, function(err, comment) {
    if (err) console.log(err);
    else {
      campground.comments.push(comment);
      campground.save();
      console.log("Created new comment");
      resolve();
    }
  });
}

function new_addCamps(seed) {
  return new Promise((resolve, reject) => {
    Camp.create(seed, function(err, campground) {
      if (err) reject(err);
      else {
        console.log("Added a campground");
        addComments(campground, cmt,resolve);
      }
    });
  });
}

同時不能再使用forEach而是使用for循環(huán):

(async function (){
for(let i=0;i<data.length;i++){
await addCamps(data[i]);
}
})();
2017年1月11日 01:30
編輯回答
維他命

樓上正解,舉個簡單的例子
for (var i=0;i<3;i++){

setTimeout(function(){console.log(i)},100)

}
你覺得輸出結(jié)果是什么?

答案是三個3
異步回調(diào),普通的回調(diào)是沒問題的,就是把setTimeout去掉,變成一個閉包函數(shù)。
輸出是0,1,2
但是異步回調(diào)會讓事件輪詢的順序產(chǎn)生變化。

特別詳細(xì)的去百度一下Js的事件輪詢機(jī)制吧

2017年11月23日 08:16