2015-07-11 31 views
4

我正在使用Babel作爲一個項目,我被一個非常基本的問題困住了。我很習慣jQuery的遞延對象,我在努力尋找其ES2015等同,這裏是我基本上要:

// file1.js 
let dfd = new Promise() 

function functionCalledAtSomePoint(thing) { 
    dfd.resolve(thing) 
} 

export default { dfd } 


// file2.js 
import { dfd } from './file1' 

dfd.then((thing) => { 
    console.log('Yay thing:', thing) 
}) 

應該用什麼來糾正這種簡單的遞延正確的方法是什麼?

編輯與royhowie的回答是:

// file1.js 
let thing 
function getThing(_thing) { 
    return new Promise((resolve) => { 
     if (el) { 
      thing = new Thing(el) 
     } 
     resolve(thing) 
    }) 
} 

function functionCalledAtSomePoint(el) { 
    getThing(el) 
} 

export default { getThing } 


// file2.js 
import { getThing } from './file1' 

getThing.then((thing) => { 
    console.log('Yay thing:', thing) 
}) 
+0

巴貝爾有一個資料「入門」指南,該指南在ES6談到承諾:https://babeljs.io/docs/learn-es2015/#promises – royhowie

+0

我先讀了它,然後MDN,然後谷歌和我仍然無法得到我的頭:/ – Calvein

+0

可能重複[如何將現有的回調API轉換爲承諾?](http://stackoverflow.com/q/22519784/1048572) – Bergi

回答

4

可以承諾直接導出(而不是函數)樣你有,但是你將只能使用它(.then)一次,這可能是而不是你想要什麼。

相反,你應該導出它返回一個Promise功能:

文件1.js

import User from '../models/user' 

export function getUsersFromDatabase() { 
    return new Promise((resolve, reject) => { 
     User.find({}, (err, users) => { 
      return err ? reject(err) : resolve(users) 
     }) 
    }) 
} 

file2.js

import { getUsersFromDatabase } from './file1' 

getUsersFromDatabase().then((users) => { 
    // success 
}).catch((err) => { 
    // no users 
}) 

您可以使用默認承諾執行,but it much slower than 3rd party modules,例如bluebird(我非常推薦使用)。

+0

@JaromandaX然後他可以使用默認實現(目前非常慢)。藍鳥是符合Promise/A +標準的,所以它應該作爲一個直接替代品。 – royhowie

+0

@zerkms他們的工作方式完全一樣 – royhowie

+0

@zerkms我找不到確切的網頁,但https://github.com/petkaantonov/bluebird/tree/master/benchmark是告訴。請注意,本機實現的速度慢了一個數量級(389 v。3532)。 – royhowie

5

我很習慣jQuery的遞延對象,我在努力尋找其ES2015相當於

如果必須使用推遲,這應該工作

function makeDeferred() { 
    var res, rej; 
    let dfd = new Promise(function(resolve, reject) { 
     res = resolve; 
     rej = reject; 
    }); 
    dfd.resolve = res; 
    dfd.reject = rej; 
    return dfd; 
} 
let dfd = makeDeferred(); 

然而,重寫你的代碼,以避免這樣的kludge將是可取的(但不是不可避免的 - 我仍然有一個一段代碼我無法擺脫延期諾言,所以我覺得y我們的痛苦

+0

這是相當於承諾jquery的承諾 - 正如我在我的回答中所述,你應該避免'延期模式',但現有的代碼可能是一個噩夢轉換 –

+0

這是一個很好的答案,有人可能想要仍然使用$ .Deferred但它不是我的情況。 – Calvein

+0

我誤解了那個問題:p –

0

本課程將允許您使用常規Promise方法以及額外的resolve(value)方法。這應該會給你類似jQuery.deferred()的功能。

function DeferredPromise() { 
    var _resolve = null; 
    var _reject = null; 

    this.promise = new Promise(function(resolve, reject) { 
     _resolve = resolve; 
     _reject = reject; 
    }); 
    this.then = function() { 
     return this.promise.then(...arguments); 
    } 
    this.catch = function() { 
     return this.promise.catch(...arguments); 
    } 
    this.resolve = function() { 
     _resolve(...arguments); 
    } 
    this.reject = function() { 
     _reject(...arguments); 
    } 
} 

然後你可以使用它來創建一個新的DeferredPromise

var p = new DeferredPromise(); 

等待它:

p.then(val => { 
    console.log('val(1)', val); 
}) 

也許等待它的另一個時間,你也可以IT連鎖帶正規Promise

p.then(val => { 
    console.log('val(2)', val); 
    return 42; 
}).then(val => { 
    console.log('.then(somethingElse)', val); 
}) 
.catch(err => { console.error('err', err); }) 

,並解決它,只要你想要的:

p.resolve({ username: 'Luke.Skywalker', age: 42 });