關(guān)于Js的promise没讲、generator眯娱、async、await

關(guān)于Js的promise爬凑、generator徙缴、async、await

第一章 前言

? 大家都知道Javascript是單線程的嘁信,而且他的耗時(shí)操作是異步的于样,比如網(wǎng)絡(luò)請(qǐng)求以及IO操作。在一般來(lái)說(shuō)潘靖,我們比較喜歡他的異步穿剖,因?yàn)楫惒叫时容^高,資源得到了合理的利用卦溢,但是有的時(shí)候我們?yōu)榱丝刂屏鞒毯啵伊鞒汤锩娲嬖谝恍┖臅r(shí)操作秀又,如果還是使其異步的話就會(huì)使得我們的流程非常難控制,所以這個(gè)時(shí)候我們就要同步執(zhí)行我們的耗時(shí)操作啄刹。

第二章 關(guān)于單線程

? 有的時(shí)候我會(huì)想涮坐,javascript既然是單線程的,那為什么他又可以異步的呢誓军?(因?yàn)樽鳛樾“椎奈业恼J(rèn)知來(lái)說(shuō)袱讹,異步就是開(kāi)個(gè)新的線程去執(zhí)行這個(gè)耗時(shí)任務(wù) o(╥﹏╥)o)

? 這里就有一個(gè)主線程的概念了,所謂單線程就是Javascript 引擎在解釋昵时、處理javascript代碼的線程只有一個(gè)捷雕,這個(gè)線程就是主線程。實(shí)際上瀏覽器還存在其他線程壹甥,比如處理網(wǎng)絡(luò)請(qǐng)求救巷、處理DOM等的線程,這些線程稱為工作線程句柠,這里說(shuō)的單線程的意思是javascript無(wú)論什么時(shí)候都只有一個(gè)線程在運(yùn)行javascript程序

這樣的好處就是javascript的單線程簡(jiǎn)化了處理事件的機(jī)制浦译,不必理會(huì)資源競(jìng)爭(zhēng)和線程同步這些復(fù)雜的問(wèn)題。

第三章 關(guān)于同步溯职、異步精盅、阻塞、非阻塞

同步和異步關(guān)注的是消息通信機(jī)制 (synchronous communication/ asynchronous communication)

阻塞和非阻塞關(guān)注的是程序在等待調(diào)用結(jié)果(消息谜酒,返回值)時(shí)的狀態(tài).

  • 同步

    同步就是程序一行一行的執(zhí)行代碼叹俏,只有等上一行的代碼執(zhí)行完了,才會(huì)繼續(xù)執(zhí)行下一行代碼

    function sync{
      console.log("1")
      console.log("2")
      console.log("3")
      console.log("4")
      console.log("5")
    }
    sync() // 輸出 1僻族,2粘驰,3,4述么,5
    
  • 阻塞

    阻塞調(diào)用是指在返回結(jié)果之前蝌数,程序會(huì)等待這個(gè)調(diào)用直到這個(gè)調(diào)用返回結(jié)果,才會(huì)繼續(xù)往下執(zhí)行

    function block(){
        console.log(1);
        console.log(2);
        // 這里假設(shè)這個(gè)文件比較大度秘,需要花費(fèi)1分鐘才能打開(kāi)它
        let res = fs.readFileSync("xxx.json")
        console.log(3);
        console.log(4);
    }
    block() // 輸出 1籽前,2,(這里過(guò)了1分鐘之后) 繼續(xù)輸出 3敷钾,4    
    
  • 異步

    異步操作在js中的原理是當(dāng)遇到異步操作時(shí)(比如網(wǎng)絡(luò)請(qǐng)求、IO耗時(shí)操作等),這個(gè)異步任務(wù)會(huì)掛起肄梨,放到任務(wù)隊(duì)列阻荒,任務(wù)隊(duì)列的任務(wù)會(huì)等到任務(wù)隊(duì)列之外的所有代碼執(zhí)行完畢之后在執(zhí)行,因此程序的執(zhí)行順序可能和代碼中的順序不一致众羡。

    function async() {
        console.log("開(kāi)始準(zhǔn)備請(qǐng)求數(shù)據(jù)");
        console.log("馬上要開(kāi)始請(qǐng)求了...");
        $.ajax('http://xxxx.com', function(resp) {
            console.log('請(qǐng)求完成~');
        });
        console.log("請(qǐng)求發(fā)出完成");
    }
    async()
    // 開(kāi)始準(zhǔn)備請(qǐng)求數(shù)據(jù)
    // 馬上要開(kāi)始請(qǐng)求了...
    // 請(qǐng)求發(fā)出完成
    // 請(qǐng)求完成~
    
  • 非阻塞

    非阻塞調(diào)用是指程序執(zhí)行到非阻塞調(diào)用時(shí)侨赡,會(huì)將該任務(wù)放置任務(wù)隊(duì)列,然后程序繼續(xù)往下執(zhí)行,等任務(wù)隊(duì)列以外的代碼都執(zhí)行完成之后,才開(kāi)始執(zhí)行任務(wù)隊(duì)列中的方法

    function nonBlocking(){
        console.log("開(kāi)始讀文件了");
        fs.readFile("./package.json",(err,data)=>{
            console.log("文件讀取完成...");
        })
        console.log("發(fā)起文件讀取完畢");
    }
    nonBlocking()
    // 開(kāi)始讀文件了
    // 發(fā)起文件讀取完畢
    // 文件讀取完成...
    

第四章 異步編程的四種方式

"異步模式"非常重要羊壹。在瀏覽器端蓖宦,耗時(shí)很長(zhǎng)的操作都應(yīng)該異步執(zhí)行,避免瀏覽器失去響應(yīng)油猫,最好的例子就是Ajax操作稠茂。在服務(wù)器端,"異步模式"甚至是唯一的模式情妖,因?yàn)閳?zhí)行環(huán)境是單線程的睬关,如果允許同步執(zhí)行所有http請(qǐng)求,服務(wù)器性能會(huì)急劇下降毡证,很快就會(huì)失去響應(yīng)电爹。 ------摘自 阮一峰

  • 回調(diào)函數(shù)

    /**
     * 吃飯
     */
    function eat(){
        console.log("開(kāi)始吃飯");
    }
    /**
     * 洗手
     * @param {function} afterTask 
     */
    function wishHands(afterTask) {
        /**
         * 洗手要洗一分鐘
         */
        console.log("開(kāi)始洗手...");
        setTimeout(_=>{
            console.log("手洗干凈了...");
            afterTask()
        },1000*60)
    }
    
    /**
     * 吃飯前需要洗手
     */
    wishHands(eat)
    // 開(kāi)始洗手...
    // 手洗干凈了...
    // 開(kāi)始吃飯
    
  • 事件監(jiān)聽(tīng)

    function task(){
        console.log("task start");
        setTimeout(_=>{
            task.trigger('finish') // 觸發(fā)finish事件
        },1000*3)
    }
    function afterTask(){
        console.log("task finish");
    }
    // 監(jiān)聽(tīng)finish事件
    task.on('finish',afterTask)
    task()
    

    這種方法的優(yōu)點(diǎn)是比較容易理解,可以綁定多個(gè)事件料睛,每個(gè)事件可以指定多個(gè)回調(diào)函數(shù)丐箩,而且可以"去耦合"(Decoupling),有利于實(shí)現(xiàn)模塊化恤煞。缺點(diǎn)是整個(gè)程序都要變成事件驅(qū)動(dòng)型屎勘,運(yùn)行流程會(huì)變得很不清晰。

  • 發(fā)布/訂閱

    我們假定阱州,存在一個(gè)"信號(hào)中心"挑秉,某個(gè)任務(wù)執(zhí)行完成,就向信號(hào)中心"發(fā)布"(publish)一個(gè)信號(hào)苔货,其他任務(wù)可以向信號(hào)中心"訂閱"(subscribe)這個(gè)信號(hào)犀概,從而知道什么時(shí)候自己可以開(kāi)始執(zhí)行。這就叫做"發(fā)布/訂閱模式"(publish-subscribe pattern)夜惭,又稱"觀察者模式"(observer pattern)姻灶。

    這個(gè)模式有多種實(shí)現(xiàn),下面采用的是Ben Alman的Tiny Pub/Sub诈茧,這是jQuery的一個(gè)插件产喉。

    function task(){
        console.log("task start");
        setTimeout(_=>{
            jQuery.publish("finish")
        },1000*3)
    }
    function afterTask(){
        console.log("task finish");
    }
    jQuery.subscribe('finish',afterTask)
    task()
    
  • Promise 對(duì)象

    Promises對(duì)象是CommonJS工作組提出的一種規(guī)范,目的是為異步編程提供統(tǒng)一接口敢会。

    它的思想是曾沈,每一個(gè)異步任務(wù)返回一個(gè)Promise對(duì)象,該對(duì)象有一個(gè)then方法鸥昏,允許指定回調(diào)函數(shù)塞俱。

    function task(){
        console.log("開(kāi)始執(zhí)行任務(wù)");
        return new Promise((resolve,reject)=>{
            setTimeout(_=>{
                resolve("我完成啦")
            })
        })
    }
    function afterTask(){
        console.log("afterTask 開(kāi)始");
    }
    task().then(res=>{
        console.log(res);
        afterTask()
    })
    

第五章 關(guān)于Promise

? Promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強(qiáng)大吏垮。它由社區(qū)最早提出和實(shí)現(xiàn)障涯,ES6 將其寫進(jìn)了語(yǔ)言標(biāo)準(zhǔn)罐旗,統(tǒng)一了用法,原生提供了Promise對(duì)象唯蝶。

? 所謂Promise九秀,簡(jiǎn)單說(shuō)就是一個(gè)容器,里面保存著某個(gè)未來(lái)才會(huì)結(jié)束的事件(通常是一個(gè)異步操作)的結(jié)果粘我。從語(yǔ)法上說(shuō)鼓蜒,Promise 是一個(gè)對(duì)象,從它可以獲取異步操作的消息涂滴。Promise 提供統(tǒng)一的 API友酱,各種異步操作都可以用同樣的方法進(jìn)行處理。

  • 基本用法

    Promise對(duì)象是一個(gè)構(gòu)造函數(shù),接受一個(gè)包含resolve回調(diào)和reject回調(diào)參數(shù)的函數(shù)為參數(shù)柔纵,執(zhí)行結(jié)果符合預(yù)期可以調(diào)用resolve缔杉,不符合預(yù)期可以執(zhí)行reject拋出異常。

    let promise = new Promise((resolve,reject)=>{
        let res = task()
        if (res is expect) {
            resolve("good")
        }
        reject("res is not expect")
    })
    

    Promise有三種狀態(tài):執(zhí)行中搁料、已成功或详、已失敗

    resolve調(diào)用之后,promise實(shí)例的狀態(tài)就從執(zhí)行中->已成功

    reject調(diào)用之后郭计,promise實(shí)例的狀態(tài)就從執(zhí)行中->已失敗

    要對(duì)Promise的執(zhí)行結(jié)果做處理可以執(zhí)行它的then方法,then方法包含兩個(gè)參數(shù)霸琴,第一個(gè)是成功的回調(diào),第二個(gè)是失敗可選回調(diào):

    promise.then(res=>{
        console.log("exec success:"+res); // 這里res就是resolve的參數(shù)
    },err=>{
        console.log("exec fail:"+err);  // 這里 err就是reject的參數(shù)
    })
    
  • Promise 實(shí)例的屬性

    promise.then(res=>{})  // 可以理解成結(jié)果的回調(diào)
    promise.catch(reason=>{}) // 執(zhí)行失敗或發(fā)生異常的回調(diào)
    promise.finally(_=>{})  // 執(zhí)行結(jié)束的回調(diào)昭伸,不管成功與否都會(huì)回調(diào)
    
    // then()方法和catch()返回的結(jié)果仍然是promise梧乘,所以可以使用鏈?zhǔn)綄懛?
    //寫法一
    promise.then(res=>{
    
    },err=>{
    
    }).finally(_=>{
        
    })
    // 寫法二
    promise.then(res=>{
    
    }).catch(err=>{
        
    }).finally(_=>{
        
    })
    
    // 寫法一和寫法二效果是一樣的
    
  • Promise靜態(tài)方法

    • Promise.all(...promise[])將多個(gè) Promise 實(shí)例,包裝成一個(gè)新的 Promise 實(shí)例
    Promise.all(p1,p2,p3)
    

    上面代碼中庐杨,Promise.all()方法接受一個(gè)數(shù)組作為參數(shù)选调,p1p2灵份、p3都是 Promise 實(shí)例仁堪,如果不是,就會(huì)先調(diào)用下面講到的Promise.resolve方法填渠,將參數(shù)轉(zhuǎn)為 Promise 實(shí)例弦聂,再進(jìn)一步處理。另外氛什,Promise.all()方法的參數(shù)可以不是數(shù)組莺葫,但必須具有 Iterator 接口,且返回的每個(gè)成員都是 Promise 實(shí)例枪眉。

    p的狀態(tài)由p1捺檬、p2p3決定瑰谜,分成兩種情況欺冀。

    (1)只有p1p2萨脑、p3的狀態(tài)都變成fulfilled隐轩,p的狀態(tài)才會(huì)變成fulfilled,此時(shí)p1渤早、p2职车、p3的返回值組成一個(gè)數(shù)組,傳遞給p的回調(diào)函數(shù)鹊杖。

    (2)只要p1悴灵、p2p3之中有一個(gè)被rejected骂蓖,p的狀態(tài)就變成rejected积瞒,此時(shí)第一個(gè)被reject的實(shí)例的返回值,會(huì)傳遞給p的回調(diào)函數(shù)登下。

    • Promise.race(...promise[])方法同樣是將多個(gè) Promise 實(shí)例茫孔,包裝成一個(gè)新的 Promise 實(shí)例。
    Promise.race(p1,p2,p3)
    

    上面代碼中被芳,只要p1缰贝、p2p3之中有一個(gè)實(shí)例率先改變狀態(tài)畔濒,p的狀態(tài)就跟著改變剩晴。那個(gè)率先改變的 Promise 實(shí)例的返回值,就傳遞給p的回調(diào)函數(shù)侵状。

    Promise.race()方法的參數(shù)與Promise.all()方法一樣赞弥,如果不是 Promise 實(shí)例,就會(huì)先調(diào)用下面講到的Promise.resolve()方法壹将,將參數(shù)轉(zhuǎn)為 Promise 實(shí)例嗤攻,再進(jìn)一步處理。

    • Promise.resolve(task) 將一個(gè)方法包裝成promise诽俯,比如他ajax請(qǐng)求
    • Promise.reject(task) 同上
  • 更多詳情請(qǐng)參考阮一峰 promise

第六章 關(guān)于Generator

Generator 函數(shù)是 ES6 提供的一種異步編程解決方案妇菱,語(yǔ)法行為與傳統(tǒng)函數(shù)完全不同。

  • 示例

    function* generatorTest(){
        console.log("generator test start ");
        yield console.log("step 1");
        yield console.log("step 2");
        yield console.log("step 3");
        console.log("generator test finish");
    }
    
    let test = generatorTest()
    // 什么都沒(méi)有
    test.next()
    // generator test start 
    // step 1
    test.next()
    // step 2
    test.next()
    // step 3
    test.next()
    // generator test finish
    test.next()
    // 什么都沒(méi)有
    

    ? 從上面實(shí)例中我們可以看出來(lái)暴区,generator方法的聲明需要加上*號(hào)闯团,里面還有關(guān)鍵字yield調(diào)用 Generator 函數(shù)后,該函數(shù)并不執(zhí)行仙粱,返回的也不是函數(shù)運(yùn)行結(jié)果房交,而是一個(gè)指向內(nèi)部狀態(tài)的指針對(duì)象。然后需要執(zhí)行next方法伐割,內(nèi)部指針就從函數(shù)頭部或上一次停下來(lái)的地方開(kāi)始執(zhí)行候味,直到遇到下一個(gè)yield表達(dá)式(或return語(yǔ)句)為止刃唤。換言之,Generator 函數(shù)是分段執(zhí)行的白群,yield表達(dá)式是暫停執(zhí)行的標(biāo)記尚胞,而next方法可以恢復(fù)執(zhí)行

  • 更多詳情請(qǐng)參考阮一峰 generator

第七章 async和await

ES2017 標(biāo)準(zhǔn)引入了 async 函數(shù),使得異步操作變得更加方便帜慢。

async 函數(shù)是什么笼裳?一句話,它就是 Generator 函數(shù)的語(yǔ)法糖粱玲。

  • 使用async與generator的對(duì)比

    const fs = require('fs');
    const readFile = function (fileName) {
      return new Promise(function (resolve, reject) {
        fs.readFile(fileName, function(error, data) {
          if (error) return reject(error);
          resolve(data);
        });
      });
    };
    // 使用generator
    const gen = function* () {
      const f1 = yield readFile('/etc/fstab');
      const f2 = yield readFile('/etc/shells');
      console.log(f1.toString());
      console.log(f2.toString());
    };
    // 使用async
    const asyncReadFile = async function () {
      const f1 = await readFile('/etc/fstab');
      const f2 = await readFile('/etc/shells');
      console.log(f1.toString());
      console.log(f2.toString());
    };
    // 一比較就會(huì)發(fā)現(xiàn)躬柬,async函數(shù)就是將 Generator 函數(shù)的星號(hào)(*)替換成async,將yield替換成await抽减,僅此而已允青。
    
  • 基本用法

    async聲明的方法返回的是一個(gè)promise對(duì)象,可以使用then方法添加回調(diào)函數(shù)胯甩,當(dāng)程序執(zhí)行的過(guò)程中昧廷,一旦遇到await 聲明的語(yǔ)句,程序?qū)?huì)等待這個(gè)語(yǔ)句返回結(jié)果之后才會(huì)執(zhí)行后面的方法偎箫。

    • 實(shí)例一:
    // 這里假設(shè)getStudentIdByNumber和getStudentScoreById都是耗時(shí)的網(wǎng)絡(luò)請(qǐng)求木柬,所以是異步的
    async function getStudentScoreByStudentNumber(studentNumber)
    {
          // 根據(jù)學(xué)號(hào)拿到id
        let studentId = await getStudentIdByNumber(studentNumber)
        // 通過(guò)id獲取分?jǐn)?shù)
        let score = await getStudentScoreById(studentId)
        // 獲取分?jǐn)?shù)后返回
        return score
    }
    // 使用then去獲取執(zhí)行結(jié)果
    getStudentScoreByStudentNumber("662297").then(score=>{
        console.log(score);  
    })
    
    • 實(shí)例二:
    function request(){
        return new Promise((resolve,reject)=>{
            setTimeout(resolve,1000*5)
        })
    }
    async function networkTask(){
        console.log("request start");
        await request()
        console.log("request finish");
    }
    networkTask()
    // 輸出 request start
    // 等待5秒
    // 輸出 request finish
    

1、正常情況下淹办,await命令后面是一個(gè) Promise 對(duì)象档插,返回該對(duì)象的結(jié)果漓雅。如果不是 Promise 對(duì)象州弟,就直接返回對(duì)應(yīng)的值暇咆。

2、根據(jù)語(yǔ)法規(guī)則副硅,await命令只能出現(xiàn)在 async函數(shù)內(nèi)部姥宝,否則都會(huì)報(bào)錯(cuò)。

3恐疲、await命令后面的Promise對(duì)象腊满,運(yùn)行結(jié)果可能是rejected,所以最好把await命令放在try...catch代碼塊中培己。

第八章 注意

  • 如果多個(gè)異步請(qǐng)求之間存在前后關(guān)系碳蛋,可以像上一章一樣使用await來(lái)改造成同步

  • 如果多個(gè)await命令后面的異步操作,如果不存在繼發(fā)關(guān)系省咨,最好讓它們同時(shí)觸發(fā)肃弟。

    let foo = await getFoo();
    let bar = await getBar();
    // 可寫成
    // 寫法一
    let [foo, bar] = await Promise.all([getFoo(), getBar()]);
    
    // 寫法二
    let fooPromise = getFoo();
    let barPromise = getBar();
    let foo = await fooPromise;
    let bar = await barPromise;
    
  • await命令只能用在async函數(shù)之中,如果用在普通函數(shù),就會(huì)報(bào)錯(cuò)笤受。

  • 如果將forEach方法中使用async函數(shù)會(huì)有問(wèn)題

    // 錯(cuò)誤一
    async function dbFuc(db) {
      let docs = [{}, {}, {}]; 
      // 報(bào)錯(cuò)
      docs.forEach(function (doc) {
        await db.post(doc);
      });
    }
    // 錯(cuò)誤二
    function dbFuc(db) { //這里不需要 async
      let docs = [{}, {}, {}];
      // 可能得到錯(cuò)誤結(jié)果
      docs.forEach(async function (doc) {
        await db.post(doc);
      });
    }
    // 改成for of 準(zhǔn)確
    async function dbFuc(db) {
      let docs = [{}, {}, {}];
      for (let doc of docs) {
        await db.post(doc);
      }
    }
    // 改成reduce
    async function dbFuc(db) {
      let docs = [{}, {}, {}];
      await docs.reduce(async (_, doc) => {
        await _;
        await db.post(doc);
      }, undefined);
    }
    

參考資料

阮一峰 異步編程的四種方法

阮一峰 promise

阮一峰 generator

阮一峰 async

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末穷缤,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子箩兽,更是在濱河造成了極大的恐慌绅项,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件比肄,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡囊陡,警方通過(guò)查閱死者的電腦和手機(jī)芳绩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)撞反,“玉大人妥色,你說(shuō)我怎么就攤上這事《羝” “怎么了嘹害?”我有些...
    開(kāi)封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)吮便。 經(jīng)常有香客問(wèn)我笔呀,道長(zhǎng),這世上最難降的妖魔是什么髓需? 我笑而不...
    開(kāi)封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任许师,我火速辦了婚禮,結(jié)果婚禮上僚匆,老公的妹妹穿的比我還像新娘微渠。我一直安慰自己,他們只是感情好咧擂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布逞盆。 她就那樣靜靜地躺著,像睡著了一般松申。 火紅的嫁衣襯著肌膚如雪云芦。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天攻臀,我揣著相機(jī)與錄音焕数,去河邊找鬼。 笑死刨啸,一個(gè)胖子當(dāng)著我的面吹牛堡赔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播设联,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼善已,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼灼捂!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起换团,我...
    開(kāi)封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤悉稠,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后艘包,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體的猛,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年想虎,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了卦尊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡舌厨,死狀恐怖岂却,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情裙椭,我是刑警寧澤躏哩,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站揉燃,受9級(jí)特大地震影響扫尺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜炊汤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一器联、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧婿崭,春花似錦拨拓、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至授瘦,卻和暖如春醋界,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背提完。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工形纺, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人徒欣。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓逐样,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子脂新,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容