Home php c# sql c c++ javascript python java go android git linux asp.net django .net node.js ios xcode cocoa iphone mysql tomcat mongodb bash objective-c scala visual-studio apache elasticsearch jar eclipse jquery ruby-on-rails ruby rubygems android-studio spring lua sqlite emacs ubuntu perl docker swift amazon-web-services svn html ajax xml java-ee maven intellij-idea rvm macos unix css ipad postgresql css3 json windows-server vue.js typescript oracle hibernate internet-explorer github tensorflow laravel symfony redis html5 google-app-engine nginx firefox sqlalchemy lucene erlang flask vim solr webview facebook zend-framework virtualenv nosql ide twitter safari flutter bundle phonegap centos Register | Login | Edit Tags | New Questions | 繁体 | 简体


10 questions online user: 33

0
votes
answers
12 views
+10

同時啓動一個線程5次?

-3

我想同時執行五次cmd命令。所以我創建了一個線程,它可以執行命令並啓動線程五次。它是否正確 ?同時啓動一個線程5次?

MyRunnable r1 = new MyRunnable(); 
     ExecutorService executor = Executors.newFixedThreadPool(5); 

     for (int i = 0; i < 5; i++) { 
      executor.execute(r1); 
     } 

.......

@Override 
    public void run() 
    { 
     try { 
      // Execute command 
      String command = "cmd /c start cmd.exe"; 
      Process child = Runtime.getRuntime().exec(command); 

      // Get output stream to write from it 
      OutputStream out = child.getOutputStream(); 

      out.write("cd C:/ /r/n".getBytes()); 
      out.flush(); 
      out.write("dir /r/n".getBytes()); 
      out.close(); 
     } catch (IOException e) 
     { 

     } 
    } 
+0

你的問題是什麼? – mvd

+0

我不相信。執行時間本身需要時間。如果我沒有錯,開始一個正常的線程需要約2秒 – Amirag

+0

那麼n次執行線程的正確方法是什麼? – seriously

沙发
0
0

而不是使用,MyRunnable r1 = new MyRunnable(); 使用Runnable r1 = new MyRunnable();

要執行線程,我們可以使用execute()方法或submit()。 你的代碼對我來說很不錯。

確保ExecutorService已關閉。要關閉ExecutorService,可以使用shutdown() shutdownNow()。 另外可以使用awaitTermination()來等待所有線程終止。

0
votes
answers
12 views
+10

無法使用Arraylist.get方法,它顯示「不兼容的操作數類型對象和int」

0

我試圖從用戶採取未知數量的整數(直到用戶輸入0),並計數每個輸入的整數。我想,在完成整數之後算數,我不得不將它們存儲在一個數組中。我做了一些研究並意識到創建一個長度未指定的Array的唯一方法是ArrayList是唯一的方法。但我的代碼,這部分顯示錯誤:無法使用Arraylist.get方法,它顯示「不兼容的操作數類型對象和int」

import java.util.Scanner; 

import java.util.ArrayList; 

public class IntegersOccurence { 

    public static void main(String[] args) { 
     Scanner input = new Scanner (System.in); 

     System.out.print("Enter the integers between 1 and 100: "); 
     ArrayList list = new ArrayList(); 
     System.out.println(list.get(0)); 
     //eclipse is showing an error in the line right below 
     while (list.get(list.size() - 1) != 0) { 
      list.add(input.nextInt()); 
     } 
    } 
} 
+0

也許你可以參考[這裏](https://stackoverflow.com/questions/18513308/what-is-the-difference-between-arraylist- arraylist-arraylistobject),因爲它可以回答你的問題:) – nkpg

沙发
0
0

的話,最好使用此代碼:

import java.util.List; 
import java.util.Scanner; 
import java.util.ArrayList; 

public class IntegersOccurence { 

    public static void main(String[] args) { 
     Scanner input = new Scanner (System.in); 

     System.out.print("Enter the integers between 1 and 100: "); 
     List<Integer> list = new ArrayList<Integer>(); 
     list.add(input.nextInt()); 
     System.out.println(list.get(0)); 
     //eclipse is showing an error in the line right below 
     while (list.get(list.size() - 1) != 0) { 
      list.add(input.nextInt()); 
     } 
    } 
} 
板凳
0
2

您使用raw type所以列表的類型爲Object不能相比int0),因此使用

ArrayList<Integer> list = new ArrayList<>(); 

Read , What is a raw type and why shouldn't we use it?


As mentioned:您在中沒有添加任何元素和調用get會導致崩潰,因爲

From docs

IndexOutOfBoundsException - if the index is out of range (index < 0 || index >= size()

這裏index>=size()是真實的(列表的大小爲0,沒有元素),所以因此例外

地板
0
0

更改如下行:

ArrayList list = new ArrayList(); 

收件人:

ArrayList<Integer> list = new ArrayList<>(); 

默認情況下,您的列表類型是Object,通過定義數據類型我們避免了運行時類型錯誤,並且檢查在編譯時完成。

+0

謝謝!這有助於消除錯誤!但它仍然顯示「線程中的異常」主「」 public static void main(String [] args){ Scanner input = new Scanner(System.in); System.out.print(「輸入1到100之間的整數:」);};
ArrayList list = new ArrayList <>();
boolean val = true;
而(VAL ==真){
如果(list.get(名單。size() - 1)== 0){
val = false;
}
否則{
list.add(input.nextInt());
}
}
}
} –

+0

有什麼異常?在線程異常 「主」 java.lang.ArrayIndexOutOfBoundsException: – HaroldSer

+0

輸入整數1到100之間-1 在java.util.ArrayList.elementData(未知來源) 在java.util.ArrayList.get(未知源) at IntegersOccurence.main(IntegersOccurence.java:16) –

0
votes
answers
12 views
+10

爲每個訂閱創建於掃描操作符的新種子對象

1

RxJS 5.5.2爲每個訂閱創建於掃描操作符的新種子對象

我有下面的代碼誰分裂的數字陣列爲對象,具有2個屬性「小」的數字越小則4和'大'其餘。

const o = from([1, 2, 3, 4, 5, 6]).pipe(
    scan<number, {}>((a, b) => { 
    if (b < 4) { 
     a['small'].push(b); 
    } else { 
     a['big'].push(b); 
    } 
    return a; 
    }, { 
    'small': [], 
    'big': [] 
    }) 
); 
console.log('subscription 1'); 
o.subscribe(x => console.log(JSON.stringify(x))); 
console.log('subscription 2'); 
o.subscribe(x => console.log(JSON.stringify(x))); 

認購1控制檯打印後:

{"small":[1,2,3],"big":[4,5,6]} // this is ok 

訂購2臺打印後:

{"small":[1,2,3,1,2,3],"big":[4,5,6,4,5,6]} // this is not ok 

有沒有開始一個新的種子對象每次有人贊同呢?

沙发
0
2

另一種選擇是將管道封裝在defer塊中,該塊將在訂閱時重建源流。

defer(() => 
    from([1, 2, 3, 4, 5, 6]).pipe(
    scan<number, {}>((a, b) => { 
     if (b < 4) { 
     a['small'].push(b); 
     } else { 
     a['big'].push(b); 
     } 
     return a; 
    }, { 
     'small': [], 
     'big': [] 
    }) 
) 
); 

每個訂閱都會調用推遲塊中的方法並訂閱結果。儘管像@arturgrzesiak提到的那樣,變異數組在函數式編程和擴展功能反應式編程中被看作反模式。

板凳
0
2

掃描累加器({ small: [], big: [] })被.push突變,這是一種反模式,可能很容易導致意外的行爲。防止改變先前發出的值

一種選擇可能是:

scan<number, {}>((a, b) => { 
    if (b < 4) { 
    return Object.assign({}, a, {small: a.small.concat([b])}); 
    } else { 
    return Object.assign({}, a, {big: a.big.concat([b])}); 
    } 
}, { 
    'small': [], 
    'big': [] 
}) 

不知道你正在試圖完成什麼,但它可能是值得看一看的partition運營商,這將產生兩個單獨的值流如const [small, big] = someStream.partition(x => x < 4);

+2

看來OP正在使用Typescript,所以你可以簡化使用ES7賦值符號'{... a,small:[... a.small,b]}' – paulpdaniels

+0

@paulpdaniels好點 –

0
votes
answers
11 views
+10

如何「嘗試啓動」從其他多個線程一個線程,JAVA

1

我在函數寫了這個:如何「嘗試啓動」從其他多個線程一個線程,JAVA

if(myThread.isAlive()) { 
} else { 
myThread.start(); 
} 

但這是不安全的,如果多個線程調用該函數的同一時間。啓動正在運行的線程會引發異常。

因此,除了在其周圍放置試衣服以外,還有其他選擇嗎?

+0

如果你不打算當線程是活做任何事情,只是沒有結果'如果{myThread.start();}(myThread.isAlive()!)' – unholysampler 2011-05-11 15:08:04

+0

@unholysampler,這不會工作無線同步 – bestsss 2011-05-11 22:27:57

+0

@bestsss:當然。這就是爲什麼我只是把它作爲評論發佈,它根本沒有解決這個問題。 – unholysampler 2011-05-12 00:42:49

沙发
0
3

使此方法同步。此外,此檢查(isAlive())是不安全的,因爲如果線程已完成,則無法再次啓動它(並且isAlive()將返回false ...)

+0

是的。當線程結束時,總是重新創建thead。這不是問題。我的目標不是讓這個方法同步,因爲我想讓其他線程同時調用它。 – karl 2011-05-11 15:20:29

+0

@karl - 我很難看出你爲什麼想要同時訪問一些對象(不一定是線程),而不是線程**。這是一個問題的處方。我想你可以在線程結束後重新啓動它。這應該會導致IllegalStateException。我會去創建新的線程。 – MByD 2011-05-11 15:45:55

+0

if(myThread.isAlive()){ } else { synchronized(thread){ if(thread.getState()== Thread.State.NEW) thread.start(); } } --->這是我的解決方案。 thx雖然。 – karl 2011-05-11 16:00:42

板凳
0
0

使用syncronized method/block?使用locks

地板
0
1

我只會在我打算啓動它時創建線程。

你可以做的是

synchronized(thread) { 
    if(thread.getState() == Thread.State.NEW) 
     thread.start(); 
} 

已經完成不會是活着的線程,但它不能被retstarted。

4楼
0
0

與每個人可能會說的相反:不要使用isAvile()或getState(),都需要將它們執行到同步中。沿着w/thread.start()並且要求線程實際上使用它自己作爲監視器(實際上它是這樣做的)

而是隻是捕獲start()的異常(IllegalThreadStateException)並忽略它。

try{ 
    thread.start() 
}catch(IllegalThreadStateException _x){ 
//ignore or log the reason, use getState(), if need be 
} 
0
votes
answers
11 views
+10

在Java中每個方法啓動一個線程

-1

我有興趣在程序中有多個線程,我的要求是在一個新線程中啓動每個方法。在Java中每個方法啓動一個線程

假設我有以下幾點:

public class A 
{ 
    int val=0; 

    public void foo() 
    { 
    for(int j=0;j<10;j++) 
    { 
     val=j; 
     Thread.Sleep(1000); 
    } 
    } 

    public int boo() 
    { 
    return val; 
    } 
} 

我想在一個單獨的類來創建這個類的一個對象像這樣

public class B 
{ 
    A myA = new A(); 
    myA.foo(); 
    int ret=myA.boo(); 
} 

我想要的是,當u調用foo()boo() ,這兩種方法必須在不同的線程上運行。所以我可以使用boo()方法的更新值"val"

請提供一些建議來解決這個問題。 在此先感謝.. :)

+1

延長'Thread',並在'運行實現()'。 http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html – hkf 2012-04-13 03:39:37

+0

就像上面提到的那樣,使用文檔來看看如何使用線程。既然你想在不同的線程上運行同一個類的方法,你可能需要添加一個條件,比如線程的名字來執行方法。 – Geek 2012-04-13 03:42:21

+0

我可以使用兩個run()方法..?因爲我想在兩個獨立的方法中執行foo()和boo()。 – user1330635 2012-04-13 03:42:52

沙发
0
2

您可以使用下面的一個新的線程運行代碼:

new Thread(new Runnable(){ 
     public void run(){ 
      //do stuff here 
     } 
    }).start(); 
+0

感謝lrAndroid,但我需要澄清如何使用run()方法執行兩個獨立線程執行兩個獨立方法的事實 – user1330635 2012-04-13 03:48:01

+0

您從foo()和boo()開始一個新線程。因此,上面的代碼實際上會在你的類中出現兩次(一次運行foo代碼,再次使用boo代碼)。 – lrAndroid 2012-04-13 03:50:10

+0

那麼每個run()方法如何知道誰調用了run(),無論是foo()還是boo()..? – user1330635 2012-04-13 03:55:02

板凳
0
0

像這樣的東西(一個最簡單的例子):

public static void main(String[] args) { 

    final A myA = new A(); 

    new Thread(new Runnable() { 
     public void run() { 
      myA.foo(); 
     }).start(); 

    new Thread(new Runnable() { 
     public void run() { 
      int ret=myA.boo(); 
     }).start(); 

    Thread.sleep(9999); 

} 

你需要製作Afinal,因爲這是與匿名類(如示例中的兩個Runnables)訪問本地變量的交易。

此外,您還必須添加volatileval(否則其他線程可能看不到它的任何變化):

volatile int val = 0; 
0
votes
answers
11 views
+10

卡桑德拉CodecNotFoundException:編解碼器找不到請求的操作

0

我有我想要映射到一列卡桑德拉卡桑德拉CodecNotFoundException:編解碼器找不到請求的操作

public enum MyEnum { 
    Aa, 
    Bb, 
    Cc, 
} 

一個枚舉領域,這是我如何註冊它

CodecRegistry myCodecRegistry = new CodecRegistry(); 
      myCodecRegistry.register(new EnumOrdinalCodec<MyEnum>(MyEnum.class)); 

      cluster = Cluster.builder().addContactPoint(cassandraHosts).withPort(cassandraPort).withCodecRegistry(myCodecRegistry).build(); 

我是能夠連接到cassandra就好了。下面是模型類

public class MyModel 
{ 
    @PartitionKey 
    @Column(name="id") 
    private String id; 

    @ClusteringColumn 
    @Column(name="name") 
    private String name = ""; 

    @Column(name="enum") 
    private MyEnum enum; 

    public MyModel(String i, String n) 
    { 
     id=i; 
     name=n 
     enum=MyEnum.Aa; 
    } 
} 

的片段,這裏是我如何創建使用CQL

CREATE TABLE IF NOT EXISTS 
tab 
    (
     name varchar , 
     id varchar, 
     enum varchar, 
     PRIMARY KEY ((id), name)); 

最後,我有我的映射代碼

manager = new MappingManager(session); 
    mapper = manager.mapper(MyModel.class); 
    accessor = manager.createAccessor(MyAccessor.class); 

這裏是表MyAccessor

@Accessor 
public interface MyAccessor{ 

    @Query("SELECT * FROM case WHERE id=? and name=? ALLOW FILTERING;") 
    MyModel readByIdAndName(String id,String name); 
} 

所以當我嘗試執行

MyModel m = new MyModel("asdasf","qw"); 
mapper.save(m); 

我得到

com.datastax.driver.core.exceptions.CodecNotFoundException: Codec not found for requested operation: [varchar <-> my.pack.MyEnum] 
    at com.datastax.driver.core.exceptions.CodecNotFoundException.copy(CodecNotFoundException.java:56) 
    at com.datastax.driver.core.exceptions.CodecNotFoundException.copy(CodecNotFoundException.java:25) 
    at com.datastax.driver.mapping.DriverThrowables.propagateCause(DriverThrowables.java:41) 
    at com.datastax.driver.mapping.Mapper.save(Mapper.java:289) 

我到底做錯了什麼?

沙发
0
3

EnumOrdinalCodec用於在int < - > Enum only之間映射。由於您的Enum基於字符串,因此請使用EnumNameCodec類。這兩個編解碼器類的Javadoc如下所示。希望能幫助到你。

EnumNameCodec

甲序列化枚舉實例作爲CQL VARCHAR處理表示由Enum.name作爲返回 其程序名稱編解碼器()。

EnumOrdinalCodec

序列化枚舉實例作爲表示由Enum.ordinal作爲返回其 序號值CQL整數A編碼解碼法()。

鏈接Javadoc

+0

謝謝!不能相信我錯過了:) – AbtPst

0
votes
answers
11 views
+10

jquery background-image

-4

如何用Jquery添加背景圖片,如果圖片的名稱是這樣的:../image(01).png,如果我以這種方式放置名稱../image01如果它工作,但不是當它有括號的圖像的名稱jquery background-image

+0

你能更好地解釋你想要什麼嗎 –

+0

沒有實際的代碼示例,不知道。但我同意,聽起來你需要擺脫這些括號。 – Snowmonkey

沙发
0
-1

聲音給我像URL編碼問題。

板凳
0
0

嘗試:/image%2801%29.png

percent+number東西被稱爲「百分比編碼」,並且是編碼符號的URL的方法,所以28是(和29是)(見here爲好)。

您沒有提供任何代碼示例,但我認爲這是問題,考慮您提供的少量信息。如果它不起作用,請編輯您的問題。另外,下一次你應該問google a bit之前,並且當你問的時候總是要包含相關的代碼示例。

+1

問題是,當我加載一個名稱中包含括號的圖像時,它不會向我顯示背景圖像,但如果圖像名稱中沒有括號,它可以正常工作,我正在使用數據庫提取圖像的名稱,所以我無法更改它們的名稱 它不起作用 $(「#preview_front」).css('background-image','url(../img/customcode/images/camaro- GT(07).PNG)'); 它正常工作 $(「#preview_front」)。css('background-image','url(../img/customcode/images/camaro-gt07.png)'); – Olbeng

+0

@Olbeng再次,你需要擺脫括號。嘗試:'$(「#preview_front」).css('background-image',url('../ img/customcode/images/camaro-gt%2807%29.png'))'。如果你從DB加載鏈接,你需要替換括號,即'extractString.replace('(','%28')' – yuvi

0
votes
answers
11 views
+10

JSONArray不正確構建

-1
JSONArray topologyInfo = new JSONArray(); 
String[] ids = {"1","2","3"}; 
JSONObject topoInfo = readTaskLog(); //returns an object like {Name:"Stack"} 
if (topoInfo != null) { 
    for (String id : ids) { 
     JSONObject tempobj=topoInfo; 
     tempobj.put("id", id)); 
     topologyInfo.put(tempobj); 
    } 
} 

我需要3和一個JSONObjects與名稱堆棧和id爲1,2 & 3.在我的JSONArray 3個對象與"id" 3 我的最終結果應該是像JSONArray不正確構建

[{ 
    "Name": "Stack", 
    "id": "1" 
}, 
{ 
    "Name": "Stack", 
    "id": "2" 
}, 
{ 
    "Name": "Stack", 
    "id": "3" 
}] 

但是我卻越來越爲

[{ 
    "Name": "Stack", 
    "id": "3" 
}, 
{ 
    "Name": "Stack", 
    "id": "3" 
}, 
{ 
    "Name": "Stack", 
    "id": "3" 
}] 
+0

我想'topologyInfo.add(tempobj);'並在循環中創建新的'JSONObject'實例。 –

+0

我們如何使用JSONArray的add? –

+1

將JSONObject添加到JSONArray不會克隆它,但是您正在多次編寫** same **對象,並在此對象引用的每個循環步驟中替換「id」。 –

沙发
0
4

這裏的問題是,你是重用相同的JSONObject在for循環的每次迭代,所以你要重寫的「ID」 v ALUE。

嘗試複製而不是對象...

JSONArray topologyInfo = new JSONArray(); 
String[] ids = {"1","2","3"}; 
JSONObject topoInfo = readTaskLog(); //returns an object like {Name:"Stack"} 
if (topoInfo != null) { 
    for (String id : ids) { 
     JSONObject tempobj=new JSONObject(topoInfo.toString()); 
     tempobj.put("id", id)); 
     topologyInfo.put(tempobj); 
    } 
} 
+0

JSONObject.getNames(topoInfo) - >在這裏拋出一個錯誤 –

+0

另一種方法是使用JSONObject tempobj = new JSONObject(topoInfo.toString());但這可能性不如 – PillHead

+0

您也可以從頭開始創建JSONObject,並使用JSONObject#元素插入'id'和'name'鍵/值對。 – LppEdd

板凳
0
1

你覆蓋了相同的屬性'id'每次迭代。
JSONObject#put確實指的是Map接口。

這是因爲:

JSONObject tempobj = topoInfo; 

你不處理一個新JSONObject,但你簡單地複製它的參考。

0
votes
answers
11 views
+10

如何在每秒鐘向var添加數字

0

作爲Javascript的初學者,我試圖製作一個點擊遊戲。我不知道如何每秒向var添加一個數字如何在每秒鐘向var添加數字

下面是目前的代碼。我不確定如何讓我的一個「沉悶的礦工」每秒自動向玩家添加硬幣。假設有兩個汽車礦工,那麼玩家每秒可以獲得4個硬幣。還有如何顯示玩家自動製作多少。

謝謝!

let borkCoins = 0; 
 

 
let dankMiner = 0; 
 

 
const earnBork =() => { 
 
    borkCoins += 1; 
 
    displayScreen(); 
 
}; 
 

 
const buydankMiner1 =() => { 
 

 
    if (borkCoins >= 20) { 
 
    dankMiner += 1; 
 
    borkCoins -= 20; 
 
    displayScreen(); 
 
    } else { 
 
    alert("Insufficient funds!") 
 
    } 
 
}; 
 

 
const displayScreen =() => { 
 
    document.getElementById("bork-coins").innerText = 
 
    borkCoins; 
 
    document.getElementById("dankMiner").innerText = 
 
    dankMiner; 
 
}; 
 

 
displayScreen();
<h3>Your BorkCoins: <span id="bork-coins"></h3> 
 

 
<img src="https://i.pinimg.com/736x/ef/6a/cf/ef6acfc481b76637b71d4a71db7de82a--dog-birthday-animal-memes.jpg" 
 
    height="80" width="80" id="bork-coins" onclick="earnBork();"> 
 
    
 
     <p>Click on Gabe the Doggo to earn a BorkCoin!</p> 
 
     
 
     <h3>Shop</h3> 
 
     
 
     <p>Dank Miner <i>(2 BorkCoins/sec)</i> 
 
    <br>Your Dank Miner(s): <span id="dankMiner"></span></p> 
 
    <button id="dank-miner" onclick="buydankMiner1();">Buy 1 (20 BorkCoins)</button>

+1

試試setTimeOut? https://developer.mozilla.org/fr/docs/Web/API/WindowTimers/setTimeout – Cedric

+0

或setInterval https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval – user184994

沙发
0
0

添加,檢查礦工的數量區間:

setInterval(() => { 
    if (dankMiner > 0) { 
    borkCoins += dankMiner; 
    displayScreen(); 
    } 
}, 1000); 
板凳
0
1

可以使用setInterval功能,做這樣的事情:

let borkCoins = 0; 
 
let dankMiner = 0; 
 

 
const earnBork =() => { 
 
    borkCoins += 1; 
 
    displayScreen(); 
 
}; 
 

 
/* Code Added */ 
 
setInterval(earnBork, 1000); 
 
/*--*/ 
 

 
const buydankMiner1 =() => { 
 
    if (borkCoins >= 20) { 
 
    dankMiner += 1; 
 
    borkCoins -= 20; 
 
    displayScreen(); 
 
    } else { 
 
    alert("Insufficient funds!") 
 
    } 
 
}; 
 

 
const displayScreen =() => { 
 
    document.getElementById("bork-coins").innerText = 
 
    borkCoins; 
 
    document.getElementById("dankMiner").innerText = 
 
    dankMiner; 
 
}; 
 

 
displayScreen();
<h3>Your BorkCoins: <span id="bork-coins"></span></h3> 
 
<img src="https://i.pinimg.com/736x/ef/6a/cf/ef6acfc481b76637b71d4a71db7de82a--dog-birthday-animal-memes.jpg" height="80" width="80" id="bork-coins" onclick="earnBork();"> 
 
<p>Click on Gabe the Doggo to earn a BorkCoin!</p> 
 
<h3>Shop</h3> 
 
<p>Dank Miner <i>(2 BorkCoins/sec)</i> 
 
    <br>Your Dank Miner(s): <span id="dankMiner"></span></p> 
 
<button id="dank-miner" onclick="buydankMiner1();">Buy 1 (20 BorkCoins)</button>

0
votes
answers
11 views
+10

使用Google Apps腳本進行條紋付款

0

試圖使用this示例代碼在Google Apps腳本中創建條紋結帳和付款。使用Google Apps腳本進行條紋付款

中將Html.HTML文件

<!DOCTYPE html> 
 
<!-- modification of https://stripe.com/docs/checkout#integration-custom --> 
 
<button id="customButton">Purchase</button> 
 

 
<script src="https://checkout.stripe.com/checkout.js"></script> 
 
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 
 

 
<script> 
 
var handler = StripeCheckout.configure(
 
{ 
 
    key: 'pk_test_UUbDY16wDCECOujIs0vQ2vTi', 
 
    image: 'https://i.imgur.com/M0ku9HH.png', 
 
    token: function(token) 
 
    { 
 
    // Use the token to create the charge with a server-side script. 
 
    // You can access the token ID with `token.id` 
 
    google.script.run.withSuccessHandler(chargeSuccess) 
 
    google.script.run.withFailureHandler(chargeFailure) 
 
    google.script.run.processCharge(token); 
 
    } 
 
} 
 
); 
 

 
$('#customButton').on('click', function(e) 
 
{ 
 
    // Open Checkout with further options 
 
    handler.open(
 
    { 
 
    name: 'ASD Anastasiya Ballet S.', 
 
    description: 'Pagamento online' 
 
    }); 
 
    e.preventDefault(); 
 
}); 
 
function chargeSuccess(result) { 
 
    // handle response code client side 
 
} 
 
function chargeFailure(error) { 
 
    // client error handling 
 
} 
 
</script>

這裏GS.gs文件

// IFRAME mode required 
function doGet() { 
return HtmlService.createHtmlOutputFromFile('HTML') 
.setSandboxMode(HtmlService.SandboxMode.IFRAME); 
} 

/** 
* Read Stripe token passed from google.script.run instead of 
* using a form POST request - which can't happen in HtmlService. 
* 
* @param {Object} token from checkout.js 
* @return {number} HTTP Response code 
*/ 
function processCharge(token) { 


var tokenId = token.id; 
var stripeEmail = token.email; 

// Create a Customer (optional) 
/* 
var path = "/customers"; 
var customer = Stripe_PostRequest(path, [], [], { 
    "description": "test customer", 
    "source": tokenId, 
    "email": stripeEmail 
}); 

var custId = JSON.parse(customer.getContentText()).id; 
*/ 

// Create a Charge 
path = "/charges"; 
var charge = Stripe_PostRequest(path, [], [], { 
    "currency": "usd", 
    "amount": "500", 
    //"customer": custId 
}); 

return charge.getResponseCode(); 
} 

/** 
* Generic function for making a POST request to the Stripe API. 
* Provided by Stripe support 
* 
* @param {string} path 
* @param {Object} parameters 
* @return {HTTPResponse} 
*/ 
var Stripe_PostRequest = function(path, fields, expandableFields, parameters) { 
    // Expand related fields when accessing sub-properties 
    // (e.g. `customer.email` should expand the customer 
    // object when retrieving a charge). 
    if (expandableFields !== undefined) { 
    parameters["expand[]"] = []; 
    fields.forEach(function(field) { 
     field = field.split(".")[0]; 
     if (expandableFields.indexOf(field) !== -1) { 
     parameters["expand[]"].push("data." + field); 
     } 
    }); 
    } 

    var scriptProperties = PropertiesService.getScriptProperties(); 
    var secret = scriptProperties.getProperty('testSecret'); 

    var options = { 
    "method" : "post", 
    "headers": { 
     "Authorization": "Bearer " + secret, 
     "User-Agent": "Stripe Example/0.1" 
    } 
    }; 
    var url = "https://api.stripe.com/v1" + path + serializeQueryString(parameters); 
    return UrlFetchApp.fetch(url, options); 
} 

/** 
* Serialize a dictionary to a query string for GET requests 
*/ 
var serializeQueryString = function(parameters) { 
    var str = []; 
    for (var key in parameters) { 
    var value = parameters[key]; 
    if (parameters.hasOwnProperty(key) && value) { 
     if (value.map) { 
     str.push(value.map(function(array_value) { 
      return key + "=" + encodeURIComponent(array_value); 
     }).join("&")); 
     } else { 
     str.push(key + "=" + encodeURIComponent(value)); 
     } 
    } 
    } 
    return '?' + str.join("&"); 
} 

的形式,做工精細,但沒有創建費用,因爲似乎沒有令牌創建。 作爲根本不是一個JS專家,我不知道,如果功能

令牌:功能(令牌)

調用

google.script.run.processCharge(令牌);

正確執行。

+0

首先,你的函數調用看起來不工作的例子,如:google.script.run.withSuccessHandler(chargeSuccess) .withFailureHandler(chargeFailure) .processCharge(令牌); – Kos

+0

是的,我改變了它,假設不清楚。這不是問題,因爲我無法發送正確的密鑰。不確定Google Script POST創建功能是否正常工作。任何使用Google Script創建標準stripe.charges.create調用的方式。 – davide445

沙发
0
0

您的代碼失敗,因爲您已經註釋了custId - 必須提供。這樣做沒有任何壞處,它只會創建一個測試客戶。否則,在「條帶」控制面板中創建一個客戶,並將該ID複製到custId中。

您可以隨時查看「查看>執行記錄」以獲取腳本失敗原因的線索。